Bedingte Kompilierung



  • Hallo ich habe mal eine Frage zur bedingten Compilierung. Da steht in meinem Buch, da kann man die Datei die durch eine andere eingebunden wird vor einer zweiten Compilierung schützen. Der Grund ist mir eigentlich klar. Nur nun hab ich ein Problem.
    Hier erst mal der Code

    #
    include <iostream.h>
    #include "vererb.h"
    #include "vererb1.h"
    //#define mainfile a
    
    #ifndef mainfile
    #define mainfile
      code..............
    #endif
    

    also diese Zeile nehm ich rein und raus je nach angeblichem Bedarf.
    //#define mainfile a

    Diese Datei binde ich dann in die Hauptdatei ein. Wenn ich nun in der Haupdatei bin und compiliere taucht folgendes Problem auf

    mein compiler(Linker) erzählt mir folgendes
    C:\DOKUME1\Damir\LOKALE1\Temp\cca0baaa.o(.text+0x23d):vererb.cpp: undefined reference to kasten::kasten(int, int, int, int)' C:\\DOKUME~1\\Damir\\LOKALE~1\\Temp\\cca0baaa.o(.text+0x254):vererb.cpp: undefined reference tokasten::~kasten(void)'
    C:\DOKUME1\Damir\LOKALE1\Temp\cca0baaa.o(.text+0x26b):vererb.cpp: undefined reference to kasten::print(void)' C:\\DOKUME~1\\Damir\\LOKALE~1\\Temp\\cca0baaa.o(.text+0x27c):vererb.cpp: undefined reference tokasten::~kasten(void)'
    C:\DOKUME1\Damir\LOKALE1\Temp\cca0baaa.o(.text+0x8c2):vererb.cpp: undefined reference to `kasten::~kasten(void)'

    solche Sachen. Wo ist denn dann der Sinn diesr ganzen Angelegenheit?

    MFG Lazarus



  • Hallo Lazarus,

    die Fehlermeldung sagt, dass der Compiler zwar die Deklaration für die Funktionen Kasten::Kasten u.s.w. gefunden hat (in den jeweiligen Header-Dateien), aber der Linker sucht nun vergebens nach der Definition (dem compilierten Code, der in deinen cpp-Dateien steht). Meine Vermutung ist, dass du diese Dateien gar nicht kompiliert hast.

    Falls du ein Kommando wie etwa:
    dein_compiler.exe mainfile.cpp
    verwendest, versuchs mal mit:
    dein_compiler.exe mainfile.cpp vererb.cpp ...
    oder einfach:
    dein_compiler.exe *.cpp

    Eine zweite Möglichkeit wäre, dass du die Dateien zwar kompiliert hast,
    aber der Linker sie einfach nicht findet. In diesem Fall musst du dem Linker sagen, in welchem Verzeichnis er die Objektdateien (*.obj) findet. Frag halt nochmal wie das geht, falls es daran liegt.

    Was das bedingte kompilieren angeht:
    fass einfach jede Header-Datei komplett (also auch mit includes, defines u.s.w.) in solch ein Konstrukt. Bei den cpp-Dateien brauchst du das nicht zu machen, die bindest du ja eh nicht ein.

    Beispiel:

    Datei foo.h:
    #ifndef FOO_H
    #define FOO_H
    //..code..
    #endif //FOO_H

    Datei bar.h:
    #ifndef BAR_H
    #define BAR_H

    //hier wird foo.h das erste mal eingebunden, FOO_H ist noch nicht definiert
    #include "foo.h"
    ..
    //hier ist FOO_H schon definiert und es wird sozusagen eine leere Datei
    //eingebunden, damit es nicht zu doppelten Deklarationen kommt
    #include "foo.h"
    ..
    #endif //BAR_H

    Du fragst jetzt vielleicht "Ist das nicht fürchterlich kompliziert? Kann der Compiler nicht einfach erkennen, was er schon kompiliert hat?". Jetzt mal ehrlich, wer es einfach haben will, benutzt Java.

    ich hoffe, dass war einigermaßen verständlich und ich konnte dir helfen.

    MfG,
    Nick



  • Normaler Weise wird das nur innerhalb von Header-Dateien verwendet.
    Wenn du zum Beispiel eine Datei "vector.h" hast in der eine Vektor-Klasse definiert ist. Diese wird sicherlich in mehreren anderen Dateien gebraucht.
    Ohne das bedingte Kompilieren würde der Header und die entsprechende *.Cpp-Datei mehrfach kompiliert was zu Fehler führen würde.
    Deshalb schließt man die gesamte Headerdatei in einen IFDEF ein:

    #ifndef H_VECTOR     // wenn noch nicht definiert wurde diese Datei noch nicht kompiliert
    #define H_VECOTR     // in diesem Fall definieren
    
    #include "math.h"
    
    class CVector
    {
     // ...
    }
    
    #endif // nun ist diese Datei kompiliert, beim nächsten Einbinden ist H_VECTOR definiert und deshalb wird der Code innerhalb der Datei übersprungen
    

    Du musst beachten, dass alles davon eingeschlossen wird.
    Außerdem verwendet man dies nicht innerhalb der Hauptdatei, normaler Weise.



  • jupp!



  • habe eine Hauptdatei gehabt und in diese Datei hatte ich dann eine weitere cpp Datei eingebunden. Und in diese hatte ich dann zwei Headerdateien eingebunden. Habe das mit der bedingten Compilierung mißverstanden. Dann hab ich gewisse Blöcke in der Datei, die eingebunden wurde in ifndef def endif gesetzt. Dann hat der Compiler denke ich in den Headerdateien die Deklarationen gefunden aber
    dadurch, daß der Block in der CPP datei quasi unsichtbar war hat er die Definition nicht gefunden. Hatte das so verstanden mit der Compilierung daß nicht bei einem Compiliervorgang vor einer doppelten Compilierung geschützt werden soll sondern wenn schon mal übersetzt dann beim nächsten mal nicht compilieren. Suppi danke für die Erklärung

    tschu


Anmelden zum Antworten