One Definition Rule (ODR)



  • Wo wäre denn der unterschied zu nem header, der in beide ÜE eigebunden wird, und den der eigentliche compiler ja nie zu sehen bekommt?



  • So, hab den text gefunden: http://www.ddj.com/cpp/184403830
    Da steht nichts drinnen warum dein Code die ODR verletzen sollte. War nur ein allgemeiner Hinweis unnamed namespaces zu verwenden.

    Aber ich habe die Klassendefinitionen uebersehen. Camper hat recht. Die Variablendefinition verletzt die ODR zwar nicht, aber die Klassendefinition tut dies.



  • quarkquark schrieb:

    Wo wäre denn der unterschied zu nem header, der in beide ÜE eigebunden wird, und den der eigentliche compiler ja nie zu sehen bekommt?

    Ahhh die reihenfolge ist vertauscht. Gut dann nicht



  • Also, es verletzt die ODR, oder?

    Gibt es irgendeinen Compiler/Linker auf der Welt, der hier ein Fehler ausgibt?



  • Wenn er es nicht tun würde, würde mich das wundern.

    Schließlich wird zuerst Test1.cpp kompiliert, dann Test2.cpp (und noch Main.cpp...). Beide enthalten eine Klasse die den Namen "Test" hat.
    Wenn die beiden dateien zusammengelinkt werden, müsste das doch einen Linker fehler erzeugen, oder habe ich da etwas missverstanden?



  • Jochen Kalmbach schrieb:

    Also, es verletzt die ODR, oder?

    Gibt es irgendeinen Compiler/Linker auf der Welt, der hier ein Fehler ausgibt?

    g++ in Version 4.2 und 4.3 sowie comeau in Version 4.3.3 geben in maximaler Warnstufe keine Warnungen/Fehler


  • Mod

    DrPhil_Guth schrieb:

    Wenn die beiden dateien zusammengelinkt werden, müsste das doch einen Linker fehler erzeugen, oder habe ich da etwas missverstanden?

    Warum? In dem Beispiel ist nicht zu sehen, warum der Linker den Typ Test jemals benutzen müsste. Ganz analog zu mehrfach definierten Funktionen, mit dem Fall sind wir ja einigermaßen vertraut, führt das in der Regel nur zu Problemen, wenn diese Funktion tatsächlich auch benutzt wird, vorzugsweise aus einer anderen Übersetzungseinheit heraus. Benutzen muss der Linker den Typ aber nur, wenn eine andere Entität, mit der er sich sowieso auseinandersetzen muss, daran anknüpft - also ein Objekt (dass Member sein könnte, so dass der für den Linker sichtbare Name auch vom Typ abhängt) oder eine Funktion, deren Signatur von diesem Typ mit abhängt; evtl. auch ein Template. Geht man von einem simplen Compiler/Linker-Modell aus, wäre es in diesem Beispiel sehr überraschend, falls dieser ODR-Verletzung überhaupt diagnostiert werden könnte.



  • Die ODR Verletzung kann vom Linker auf jeden Fall diagnostiziert werden.

    Das Problem was ich nämlich mit dem Code habe, ist dass VC9 RTM hier "falsche" PDB-Dateien erzeugt und dort nur *einer* der beiden Typen landet...
    Der Linker hat also alle Typen und kann auch logischerweise feststellen, ob Typen doppelt (mit unterschiedlicher Definition) vorhanden sind...

    Hier ist die Aussage den MS-Supports:

    Problem/Issue:

    We have defined two structures with same name in two different CPP files. It compiles and works fine. When we see the data member information in the watch section, it shows the last compiled structure data type. This does not happen with previous version of Visual Studio.

    A: (Assessment)
    SUMMARY of TROUBLESHOOTING

    - Further to my research the issue is happening due to the PDB file is getting overwritten using the last compiled type definition information.
    - This issue does not occur in VS2008 SP1 Beta.
    - During the research we found that this not as part of the C++ standards [The C++ Standard (ISO/EC 14882:2003), section 3.2]

    RESOLUTION

    - We can keep the types under namespace or give different names for the types.


  • Mod

    Jochen Kalmbach schrieb:

    Die ODR Verletzung kann vom Linker auf jeden Fall diagnostiziert werden.

    Was ist der Linker? Ich habe mich ja bewusst nicht auf eine bestimmte Implementation bezogen - zweifellos ist es nicht prinzipiell unmöglich, derartige Fehler automatisch zu erkennen. Diese Diagnose aber in jedem Falle zu verlangen, erhöht die Komplexität einer minimalen Implementation in unerwünschter Weise - die Konsequenz ist, dass der Standard zum Verhalten bei solchen Fehlern keine Aussage trifft, dieses also undefiniert bleibt.



  • camper schrieb:

    die Konsequenz ist, dass der Standard zum Verhalten bei solchen Fehlern keine Aussage trifft, dieses also undefiniert bleibt.

    Das hab ich jetzt nicht ganz verstanden...
    Ich dachte die ODR ist Teil des Standards!?

    [The C++ Standard (ISO/EC 14882:2003), section 3.2]

    !?

    Oder doch nicht?

    Was meinst Du mit "undefiniert"? Ich dachte es *ist* gerade definiert!


  • Mod

    Jochen Kalmbach schrieb:

    camper schrieb:

    die Konsequenz ist, dass der Standard zum Verhalten bei solchen Fehlern keine Aussage trifft, dieses also undefiniert bleibt.

    Das hab ich jetzt nicht ganz verstanden...
    Ich dachte die ODR ist Teil des Standards!?

    [The C++ Standard (ISO/EC 14882:2003), section 3.2]

    !?

    Oder doch nicht?

    Was meinst Du mit "undefiniert"? Ich dachte es *ist* gerade definiert!

    Es ist definiert, ob ein Programm die ODR verletzt oder nicht. Der Standard sagt nicht, wie eine Implementation zu reagieren hat, wenn ein Programm diesen besonderen Teil der ODR verletzt.


Anmelden zum Antworten