Sicher, leere Variablen nach Wert zu übergeben, wenn sie keine Definition haben?

8

Wenn ich eine leere Variable nach Wert übergebe, obwohl sie keine Definition hat, ist sie sicher und konform?

Ich bin auf dieses Problem gestoßen, als ich an Code gearbeitet habe und | überladen habe, um den Inhalt des Vektors v :

auszudrucken %Vor%

Der Code, den ich hier vorstelle, funktioniert für mich mit g++ und clang , obwohl print eine extern Variable ohne Verknüpfung ist, aber ich frage mich, ob ich den Standard zu weit dränge. Dies ist für C ++ 11 / C ++ 14, ich denke, das ist in C ++ 17 mit inline Variablen gelöst?

Zuerst mein Code. Das Ziel ist es, Dingen wie v|print zu erlauben, einen Vektor zu drucken. Ich habe auch größere Ziele, bezogen auf Bereiche, aber ich werde mich hier auf dieses kleine Beispiel konzentrieren.

%Vor%

Verschiebe dies in eine Kopfzeile

Wenn ich dies in eine Kopfzeile verschiebe, kann ich die operator| Überladung als inline machen. Aber was ist mit print ? Ich habe gefunden, dass ich extern machen kann, um den Linkerfehler über doppelte Symbole

zu vermeiden %Vor%

Das funktioniert für mich. Irgendwie, obwohl print keine Definition hat, kann ich v|print machen. Ich schätze, es ist, weil es leer ist und daher gibt es keinen Wert zu überprüfen und daher braucht es nie eine Adresse.

Sind Compiler erforderlich, damit mein v|print -Beispiel funktioniert? Wo, um klarzustellen, print ist extern und hat keine Definition gegeben?

    
Aaron McDaid 02.11.2017, 11:07
quelle

1 Antwort

7
  

Sind Compiler erforderlich, damit mein v|print -Beispiel funktioniert? Wo, um klarzustellen, Print ist extern und hat keine Definition gegeben?

Nein. Sie verwenden odr- print (Sie rufen eine lvalue-to-rvalue-Konvertierung auf, die keinen konstanten Ausdruck ergibt), was bedeutet, dass Sie eine Definition für print benötigen. Dies ist jedoch eine der Kategorien von Fehlern, die schlecht ausgebildet sind, keine Diagnose erforderlich. Und da der betreffende Code nicht die Adresse von print an irgendeiner Stelle annimmt, ist es wahrscheinlich, dass der Compiler Code ausgibt, der keine solche Definition benötigt, und daher wird der Linker darüber auch glücklich sein. In der Regel wird es Just Work ™.

Eine bessere Lösung wäre, einfach die Deklaration zu ändern, um print constexpr :

zu machen %Vor%

Nun würde v | print nicht odr- print verwenden (da die Umwandlung von lvalue-to-rvalue jetzt ein konstanter Ausdruck wäre), also ist keine Definition überhaupt notwendig, also ist das Programm wohlgeformt.

    
Barry 02.11.2017, 12:27
quelle