Include-Probleme bei Borland C++



  • Teste mal alle möglichen Varianten des Slash.
    Ältere Compiler aus der DOS-Zeit und bis Win98-Zeit waren bezüglich des Pfades sehr wählerisch.
    Unix/Linux boten damals mehr Varianten.

    MfG f.-th.



  • Ich hab mal Backslashes geschrieben, aber daran scheint's nicht zu liegen. Es ist wirklich das Problem, dass er bei relativen include-Angaben von der aktuellen Position auf der Kommandozeile, ncht von der Position der C++-Datei ausgeht. Ein Beispiel: Wenn ich dasselbe Programm habe, aber auf der Kommandozeile in den graphics-Ordner gehe und dort dann mit tcc ..\main.cpp kompiliere, kommt der Fehler:

    Error ..\main.cpp 1: Unable to open include file 'graphics\graphics.h'

    Weil er eben wieder an einer anderen Stelle steht und die Pfade jetzt nochmal komplett anders sucht, nämlich wieder relativ von der Position auf der Kommandozeile, statt relativ von der Position der Datei, die ein #include aufruft.



  • Ich weiss nicht wie du deine Dateien sortierst und ablegst 😕

    Es ist schon ein paar Tage her das ich mich mit älteren Borland versucht habe.

    Wie viele Ordner für besondere Headerdateien benötigst du?
    Wenn es da nur um ein oder zwei Ordner geht, schau mal in der IDE nach. Da kann man entsprechende Pfade einrichten.

    Da du Wert auf diese Borland-Version legst gehe ich davon aus das dein Projekt nicht portabel sein muss.

    Weiter kann man auch direkt in Windows die Umgebung erweitern. Wer das da nicht will, dem steht auch noch die Möglichkeit offen dies über Batch-Dateien zu lösen.

    Ob das deine Version schon kann weiss ich nicht - bei etwas späteren Borland-Versionen konnte man auch noch den Compiler und Linker über die .cfg-Dateien beeinflussen.

    Denk dran, ältere DOS-Compiler wollen da nicht einen einfachen Slash oder Backslash im Quelltext, sondern den Backshlash als Doppelpack bei Pfadangaben.

    Sollten Microsoft-Compiler aus der alten Zeit an der Stelle mehr können, sprich andere Varianten des Slash akzeptieren, liegt das daran, das die sich damals auch mit UNIX-artigen Betriebssystemen beschäftigten.

    MfG f.-th.



  • f.-th. schrieb:

    Ich weiss nicht wie du deine Dateien sortierst und ablegst 😕

    Ich hab doch oben bereits ein Minimalbeispiel gezeigt.

    f.-th. schrieb:

    Wie viele Ordner für besondere Headerdateien benötigst du?
    Wenn es da nur um ein oder zwei Ordner geht, schau mal in der IDE nach. Da kann man entsprechende Pfade einrichten.

    Aber Pfade einrichten ist dafür gedacht, wenn man Dateien mit spitzen Klammern einbindet, nicht für lokale Dateien. Außerdem wäre das doch etwas komisch: Wenn ich eine Datei #include "graphic/graphic.h" habe, müsste ich also den Ordner, der über dem Ordner "graphic" liegt, hinzufügen.

    f.-th. schrieb:

    Da du Wert auf diese Borland-Version legst gehe ich davon aus das dein Projekt nicht portabel sein muss.

    Doch, gerade weil es portabel sein soll, brauche ich ja eine Lösung, die es richtig macht.

    f.-th. schrieb:

    Ob das deine Version schon kann weiss ich nicht - bei etwas späteren Borland-Versionen konnte man auch noch den Compiler und Linker über die .cfg-Dateien beeinflussen.

    Wie gesagt, das sind lokale, zum Projekt zugehörige Dateien, keine allgemeinen externen Libs. Irgend etwas in den Konfigurationsdateien einzustellen, ist für sowas generell inakzeptabel.

    f.-th. schrieb:

    Denk dran, ältere DOS-Compiler wollen da nicht einen einfachen Slash oder Backslash im Quelltext, sondern den Backshlash als Doppelpack bei Pfadangaben.

    Das hat aber nichts mit dem Slash zu tun. Es hat was damit zu tun, von wo aus er die Dateien sucht.

    f.-th. schrieb:

    Sollten Microsoft-Compiler aus der alten Zeit an der Stelle mehr können, sprich andere Varianten des Slash akzeptieren, liegt das daran, das die sich damals auch mit UNIX-artigen Betriebssystemen beschäftigten.

    Es hat nichts mit der Art des Slash zu tun. Es hat was damit zu tun, dass er jede Pfadangabe in include-Anweisungen so betrachtet, als bezieht die Pfadangabe auf die aktuelle Position des Benutzers, statt auf die Position der Datei, die das include verwendet.

    Nochmal ein Beispiel: Ich habe zwei Dateien:
    C:\PRGS\MYPROJ\HEADER.H
    C:\PRGS\MYPROJ\MAIN.CPP
    Die MAIN.CPP bindet die HEADER.H mit #include "header.h" ein.
    Wenn ich nun folgendes mache:

    C:\PRGS\MYPROJ>tcc main.cpp

    dann geht es. Wenn ich aber folgendes mache:

    C:\PRGS>tcc myproj\main.cpp

    dann sagt er, er hat die HEADER.H nicht gefunden. Warum nicht? Weil er für #include "header.h" im aktuellen Pfad (C:\PRGS) nach der HEADER.H sucht, statt in dem Pfad, in dem die Datei liegt, die den Header einbindet (C:\PRGS\MYPROJ).



  • Hast du noch ein Vor-Windows-NT-Betriebssystem zum Test am Start?

    Wenn ich mich nicht irre, war folgendes Beispiel unter DOS nicht möglich:
    C:\PRGS>tcc myproj\main.cpp ( -> main.cpp wie einfaches "Hello world" )
    auszuführen.
    Ab welcher Version der Microsoft-Betriebssysteme das möglich war?
    Ich weiss jetzt nicht, wann dein Borland-Compiler geschrieben worden ist?
    Die Borland Compiler ab Version 4.5 bis 5.5 hatten den Ruf ein wenig zickig zu sein.

    Diese Version:
    C:\PRGS\MYPROJ>tcc main.cpp
    sollte immer ab MSDOS 3.? funktionieren, wenn der Rest passt.
    Den tcc dann natürlich dem Betriebssystem entsprechend versuchen.

    Hiernach sollen die frühen 5.? Borland-Compiler unter Windows NT noch nicht richtig rund laufen:
    http://en.wikipedia.org/wiki/Borland_C%2B%2B

    Die Versionsnummer auf der Packung entspricht nicht immer der Versionsnummer mit der sich der Compiler meldet.

    MfG f.-th.



  • f.-th. schrieb:

    Hiernach sollen die frühen 5.? Borland-Compiler unter Windows NT noch nicht richtig rund laufen:
    http://en.wikipedia.org/wiki/Borland_C%2B%2B

    Oh Mann. Also noch mal: Die Fehlermeldung wird vom Compiler ausgegeben und ist für ihn ein Syntaxfehler in meinem Quellcode. Das hat nichts damit zu tun, ob der Compiler auf irgendeinem Windows nicht richtig rund läuft. Es ist eine Syntaxfehlermeldung vom Compiler und ich habe auch erklärt, wieso er sie wirft: Weil der Compiler so programmiert ist, dass er inlude-Angaben relativ zum aktuellen Arbeitsverzeichnis statt relativ zu den Codedateien betrachtet. Was sollte das mit irgendwelchen Zicken zu tun haben, die DOS-Programme manchmal unter Windows machen? Wenn es sowas wäre, würde ich doch generell sagen, dass der Compiler nicht läuft und mit einer Fehlermeldung abstürzt, oder? Oder glaubst du, ein und derselbe Compiler lässt eine include-Anweisung unter DOS durch, während er einen Syntaxfehler meldet, wenn der Compiler unter Windows ausgeführt wird? Das wäre so, als würde Visual C++ 6 unter Windows 98 ein void main() durchlassen, während dasselbe Visual C++ 6 unter Windows 7 sagt: "Sytax error: main must have return type int." Damit wäre ja auch nicht zu rechnen, oder?
    Ich befürchte, du hast gar nicht verstanden, von was für einer Art Fehler ich überhaupt spreche.



  • Oh man, wie soll ich das erklären.
    Du bewegst dich mit relativen Pfaden im Quelltext an der Schnittstelle zwischen
    Compiler und Betriebssystem.
    Diese "Schnittstelle" wurde zwischen 1995 und 2000 öfter von Microsoft überarbeitet. Das bedeutet zum einen im Extremfall bei speziellen Konstruktionen, wo damals auch relative Pfade dazugehörten, von einer Microsoft-Betriebssystem-Version zur nächsten, andere Aufrufkonventionen. Je nachdem wie genau der Compiler diese Aufrufkonvention umsetzen wollte, funktionierte so was nur bei passender Compiler-Version mit der passenden Betriebssystem-Version und dem extakt passenden Quelltext.

    Hier mal etwas aus der gleichen Zeit:
    http://www.textarchiv.alojado.de/text/erweiterte_laufwerkserkennung-ap37.html

    natürlich wirst du sofort zurückschreiben das betrifft nicht deinen Headerfall mit relativen Pfaden.

    Hier noch etwas zu relativen Pfaden aus der MSDN:
    http://msdn.microsoft.com/en-us/library/bb773740(v=vs.85).aspx
    Also werden relative Pfade wie du die verwenden möchtest von dieser Funktion erst ab W2k unterstützt.

    Da die 5er Borland C++ Compiler vor W2k geschrieben wurden, warum sollten die das mit den relativen Pfaden schon in dem Umfang beherrschen/umsetzen?

    Finde jetzt den Link nicht wieder: bei einigen Windows Versionen aus dem Zeitraum - z.B. einigen NT Versionen hatte sich ein Bug betreffs der Pfade gezeigt.

    Gab es damals nicht gar von Borland mal die Möglichkeit von einer relativ fehlerhaften Compiler Version auf die Nachfolger Version kostenlos upzudaten?

    Zusammengefasst, wenn nicht extrem wichtige Gründe was anderes verlangen, würde ich C++ Compiler, die etwa 1995 bis 2000 für Windows auf den Markt kamen, nicht mehr nutzen. Ausser dem Stress mit den relativen Pfaden: C++ 98 fällt auch noch in den Zeitraum.

    MfG f.-th.



  • f.-th. schrieb:

    Oh man, wie soll ich das erklären.
    Du bewegst dich mit relativen Pfaden im Quelltext an der Schnittstelle zwischen
    Compiler und Betriebssystem.
    Diese "Schnittstelle" wurde zwischen 1995 und 2000 öfter von Microsoft überarbeitet.

    Was interessiert es den DOS-Compiler, welche Schnittstellen in Windows überarbeitet wurden? Das ist ein DOS-Compiler, das heißt, der kann sowieso nur das alte DOS-8.3-Dateibenennungszeug. Willst du mir etwa sagen, dass ein fopen mit relativem Pfad in DOS ein anderes Ergebnis liefert als in Windows?

    f.-th. schrieb:

    natürlich wirst du sofort zurückschreiben das betrifft nicht deinen Headerfall mit relativen Pfaden.

    Genau. Aber extra dafür hab ich nochmal ein richtiges DOS in einer virtuellen Maschine aufgesetzt.

    f.-th. schrieb:

    Da die 5er Borland C++ Compiler vor W2k geschrieben wurden, warum sollten die das mit den relativen Pfaden schon in dem Umfang beherrschen/umsetzen?

    Weil es eine DOS-Anwendung ist und die sich nicht um WinAPI-Funktionen schert. Außerdem ist es eine rein programmiertechnische Angelegenheit. Wenn ich sage:
    tcc ..\main.cpp
    und die main.cpp inkludiert "graphics/graphics.h" und die "graphics/graphics.h" inkludiert "../helpers/helpers.h", dann ist die Frage, ob der Compiler die richtigen Pfade findet, eine rein programmiertechnische Angelegenheit, die ungefähr so abläuft:

    1. Splitte den Input-String "..\main.cpp" nach '\' und schneide den letzten Teil raus, um den Pfad zu bekommen:
    "..\main.cpp" --> cpp_path = ".."
    
    2. Parse die Datei.
    
    3. Wenn Du eine relative Include-Anweisung findest, übergib den aktuellen Pfad und mach folgendes:
    
    3.1. Splitte nach '/' und '\' und schneide den letzten Teil raus, um den Pfad zu bekommen:
    #include "graphics/graphics.h" --> include_path = "graphics"
    
    3.2. Nimm den ausgeschnittenen Teil und speichere den auch:
    #include "graphics/graphics.h" --> file_name = "graphics.h"
    
    3.3. Füge den ursprünglichen Pfad mit dem neuen Pfad zusammen:
    cpp_path + include_path --> "../graphics"
    
    3.4 Öffne diese Datei:
    cpp_path + include_path + file_name --> "../graphics/graphics.h"
    
    3.5 Gehe zu 3. und wiederhole das rekursiv mit allen Unterdateien mit dem aktuellen Pfad (cpp_path + include_path).
    

    Das Endergebnis für die Helperdatei wäre dann "../graphics/../helpers/helpers.h"

    Borland scheint es jedoch so gemacht zu haben:

    1. Parse die Datei "..\main.cpp".
    
    2. Wenn Du eine relative Include-Anweisung findest, such nicht nach cpp_path + include_path + file_name,
    sondern such (vom Arbeitsverzeichnis aus) nur nach include_path + file_name.
    

    Bäng: Problem!

    Alles klar? Das hat ausschließlich mit Stringbearbeitung zu tun: Ob ich beim Parsen des includes einfach nur den Pfad rausextrahiere und dann fopen mit diesem Pfad aufrufe oder ob ich vorher rekursiv den Pfad der Datei, die das include beinhaltet vorne mit ranpappe.

    Jetzt reden wir schon so lange um den heißen Brei herum mit OS-Spezifikation und dergleichen. Meinst du nicht, es wäre einfacher, wenn du den Turbo C++ mal herunterlädst und guckst, was ich meine?

    f.-th. schrieb:

    Zusammengefasst, wenn nicht extrem wichtige Gründe was anderes verlangen, würde ich C++ Compiler, die etwa 1995 bis 2000 für Windows auf den Markt kamen, nicht mehr nutzen. Ausser dem Stress mit den relativen Pfaden: C++ 98 fällt auch noch in den Zeitraum.

    Das tut nichts zur Sache. Ich will nur wissen, ob man das ändern kann oder wie die Leute damals gearbeitet haben, wenn sie ihre Codedateien in Unterordnern organisiert haben.



  • Ich stehe zwar nicht wirklich in der Materie, aber was denkst du denn, wie der Compiler die benötigten Header findet? Er wird natürlich das darunterliegende Betriebssystem fragen - und wenn sich dessen Meinung, worauf sich ein relativer Pfad zu beziehen hat, zwischen verschiedenen Versionen oder Systemen unterscheidet, kommt entsprechend Unsinn heraus.



  • OK, kannst du bestätigen, dass das das Problem ist, das mit meinem Ursprungspost zu tun hat? Ansonsten wäre es nett, wenn wir dieses Thema einstellen könnten. Es interessiert mich nicht, welche allgemeinen Probleme bei anderen Programmen auftreten könnten. Hat es was mit meinem Problem zu tun? Wenn nein, könnten wir dann bitte aufhören, um den heißen Brei herum zu reden und mal endlich auf den Punkt kommen? Der Thread ist jetzt schon auf seiner zweiten Seite und es gab bisher nicht eine einzige Antwort, die auch nur annähernd etwas mit meinem Problem zu tun hat. Wenn ich ein Problem mit meinem Abfluss habe, weil mir ein Zahnpastaverschluss reingefallen ist, will ich auch nicht seitenlang hören, dass Abflüsse durch Kalkablagerungen verstopen können. Weil das, völlig unabhängig von der generellen Richtigkeit der Aussage, absolut nichts mit meinem Problem zu tun hat.


Anmelden zum Antworten