2015-06-03 4 views
22

Nachdem nur eine Warnung vom Compiler für diese Funktion erhalten:Warum ist die zurückgegebene Adresse der lokalen Variablen oder temporär nur eine Warnung und kein Fehler?

template<class T> 
Matrix3x3<T> & operator - (Matrix3x3<T> const & p) 
{ 
    auto m = Matrix3x3<T>(p); 

    m.m11 = -m.m11; m.m12 = -m.m12; m.m13 = -m.m13; 
    m.m21 = -m.m21; m.m22 = -m.m22; m.m23 = -m.m23; 
    m.m31 = -m.m31; m.m32 = -m.m32; m.m33 = -m.m33; 

    return m; 
} 

, frage ich mich, warum eine Adresse einer lokalen Variablen oder vorübergehende Rückkehr keinen Fehler verdienen. Gibt es Umstände, unter denen Sie es tun müssen? Was ist der Grund dafür, dass es sich nur um "undefiniertes Verhalten" und nicht um eine sprachliche Einschränkung handelt?

Ich kann an keine denken.

+0

Es könnte in der Funktion als statisch deklariert werden. – OldProgrammer

+3

Würde der Compiler nicht wissen, dass es statisch ist? – Robinson

+6

Zufallsgenerierung;) – tsuki

Antwort

18

Es gibt keinen guten Grund, warum es kein Fehler sein sollte, nur die C++ standard behandelt diesen Fall nicht als solche und konforme Compiler halten sich an den Standard.

wird jedoch eine Warnung Emissions ermutigt:

§12.2.5.2 Die Lebensdauer eines temporären gebunden an den zurückgegebene Wert in einer Funktion return-Anweisung (6.6.3) nicht verlängert; Das temporäre wird am Ende des vollständigen Ausdrucks in der Return-Anweisung zerstört.

[...]

[Hinweis: Dies ist ein baumelnden Referenz vorstellen kann, und Implementierungen ermutigt eine Warnung in einem solchen Fall zu erteilen. - Endnote]

Der Schwerpunkt liegt bei mir.

+0

Basierend auf der Formatierung des C++ 14-Entwurfsstandards, den ich verknüpfte (siehe Seite 271), kann ich nicht feststellen, ob die Notiz ** 12.2 .5.3 ** nur oder insgesamt ** 12.2.5 **. Letzteres macht Sinn, aber ich würde es begrüßen, wenn jemand anderes dazu Stellung nehmen könnte. –

+0

N4296 ist ein Entwurf von C++ 1z, nach C++ 14 final (das war N4141, mit N4140 der letzte C++ 14 Entwurf). In Bezug auf deine Frage beziehen sich das Beispiel und der Hinweis, soweit ich das beurteilen kann, nur auf [12.2p5.3]. Wenn sich Beispiele oder Notizen auf die gesamte Liste beziehen, sind sie auf der gleichen Ebene wie der Hauptabsatz eingerückt. Ein Beispiel für eine solche Formatierung finden Sie in [8.5.4p7] (im Gegensatz zur Liste und Beispielen in [8.5.4p3]). Auf eine konstruktivere Anmerkung bezieht sich Ihre Antwort nur auf Provisorien, die in der return-Anweisung erstellt wurden, und nicht auf lokale Variablen, die in der Frage erwähnt werden. – bogdan

+0

Dank @bogdan, ich werde die Antwort so schnell wie möglich aktualisieren. –

7

Grund: Fehlende Konsistenz beim Generieren des Compilerfehlers.

In Ihrem gerade vorwärts Fall ist Compiler tatsächlich hilfreich, um eine Warnung zu generieren. Behandle es nur als Bonus.
Aber suchen Sie nach unten Fall, in dem Compiler dieses Problem nicht erkennen:

int& foo() 
{ 
    int i = 1; 
    static int j; 
    return i? i : j; // No warning in g++-5! 
} 

nun vom Compiler Perspektive da es Hühner, um die Komplexität der es nicht gerechtfertigt, wenn es Fehler für einen Fall und in anderen Fällen gibt Code.

Einer der Anwendungsfälle solcher Compiler-Begrenzung kann "Random Number Generation" sein, wie von @tsuki vorgeschlagen.

+0

Im Grunde genommen sind Situationen wie diese für den Compiler ziemlich schwer zu erkennen. – Robinson

+0

@Robinson, nehme an, dass es leicht zu erkennen ist. Der Compiler kann die Absicht des Coders nicht beurteilen. z.B. Wie erwähnt, wenn der Benutzer beabsichtigt, Zufallszahlen unter Verwendung solcher Funktionen zu erzeugen, ist es eine gültige Operation und der Compiler kann sie nicht durch Erzeugen eines Fehlers blockieren. – iammilind

+2

Haben Sie Warnungen tatsächlich eingeschaltet? GCC gibt für diesen genauen Fall eine 'return-local-addr'-Warnung aus. – sjdowling

Verwandte Themen