Frage

Ich habe gelesen, und die entsprechenden Klauseln über ODR in dem C ++ Standard nachzulesen, aber diese Frage bleibt noch offen zu mir. Die Norm sagt, dass die Definition einer Inline-Funktion in jeder Übersetzungseinheit angezeigt wird, in dem es verwendet wird, und die Definitionen sind in gewissem Sinne identisch sein, die in fast einer Seite beschrieben wird. Er sagt, die Token-Sequenz gleich sein muss. Ist es die lokalen Bezeichnernamen enthalten?

Mit anderen Worten: hat das folgende Programm verletzt die ODR? (Ich habe versucht, es zu testen, mich mit Visual Studio 2008 und bekam 0 Fehler und 0 Warnungen. Aber ich denke, dies beweist gar nichts, weil ich dann das Beispiel zwei völlig unterschiedliche Definitionen geändert und immer noch 0 Fehler und 0 Warnungen. In Entschuldigung von MSVC ist zu beachten, dass keine Diagnose formal für Verletzungen der ODR) erforderlich ist.

//main.cpp
inline int f(int);
int main(){
   f(3);
}
int f(int x){
   int z = x;
   return z*z;
}

//other.cpp
inline int f(int xx){
   int zz = xx;
   return zz*zz;
}
War es hilfreich?

Lösung

Identifier eine Art Token ist, jede Kennung ist ein separater Token, also ja, Sie müssen die gleiche Kennung haben, um die ODR zu respektieren. Es kann einen Unterschied in einem Compiler machen, die diese erkennen (jemand bereit ein Beispiel für como mit exportierte Vorlage zu bauen? Es einige Verletzung der ODR erkennen kann).

Dann gibt es einen Unterschied zwischen C und C ++ hier. C nicht über die ODR im Allgemeinen und die Regeln für die Inline-Funktion in C99 (es gibt keine Inline-Funktionen in C90) sind ganz anders als die von C ++. In C99, ist der Code korrekt ist. In der Tat kann man ganz andere Definition liefern. Eine Folge ist, dass in C (aber nicht in C ++), wenn Sie die gleiche Definition verwenden und diese Definition hat ein statisches Element, Sie in der Tat so viele statischen Variablen wie TU die Funktion verwenden.

Andere Tipps

Ja, es verletzt ODR. Es nutzt verschiedene Token-Sequenzen, ich weiß nicht, was so schwer ist, hier zu verstehen.

Überprüfen der ODR über Übersetzungseinheiten ist schwer (unmöglich) mit traditionellen Übersetzungstechniken. Die Norm sagt, dass „keine Diagnose erforderlich“, so dass Sie nur nicht definiertes Verhalten bekommen.

Sie können sogar subtile Fehler erhalten, wenn Sie zum Beispiel verwenden zwei verschiedene Klassen in keinem Zusammenhang Übersetzungseinheiten definiert, aber mit dem gleichen Namen. Wenn es eine virtuelle Tabelle ist es ohne Fehlermeldungen kollidieren kann (es passierte mit meinem Freund). So immer verwenden, um eine anonyme Namespaces für lokale Funktionen und Klassen.

Bezeichner sind Token, also durch die gleiche Folge von Token regieren, verletzt das Programm die ODR.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top