Ist diese statische C ++ - Analyseregel so sinnvoll wie sie ist?

Ich implementiere einige statische C ++ - Analyseregeln, und eine von ihnen verhindert, dass eine Funktion eine Referenz oder einen Zeiger auf einen Referenzparameter der Funktion zurückgibt, d. H. Die folgenden Regeln sind alle nicht konform:

int *f(int& x) { return &x; } // #1
const int *g(const int& x) { return &x; } // #2
int& h(int& x) { return x; } // #3
const int& m(const int& x) { return x; } // #4

Die Begründung hierfür lautet: "Es ist ein implementierungsdefiniertes Verhalten, ob der Referenzparameter ein temporäres Objekt oder ein Verweis auf den Parameter ist."

Das verwirrt mich jedoch, da Stream-Operatoren in C ++ auf diese Weise geschrieben sind, z.

std::ostream& operator<<(std::ostream& os, const X& x) {
    //...
    return os;
}

Ich bin mir ziemlich sicher, dass Stream-Operatoren in C ++ im Allgemeinen kein implementierungsdefiniertes Verhalten aufweisen. Was ist also los?

Nach meinem derzeitigen Verständnis würde ich erwarten, dass # 1 und # 3 gut definiert sind, auf der Grundlage, dass Provisorien nicht an nicht konstante Referenzen gebunden werden könnenint& x Bezieht sich auf ein reales Objekt, dessen Lebensdauer über den Funktionsumfang hinausgeht. Die Rückgabe eines Zeigers oder einer Referenz auf dieses Objekt ist daher in Ordnung. Ich würde erwarten, dass # 2 zwielichtig ist, weil eine vorübergehende Bindung hätte bestehen könnenconst int& xIn diesem Fall scheint es ein schlechter Plan zu sein, seine Adresse zu übernehmen. Ich bin mir nicht sicher, was # 4 angeht - mein Bauchgefühl ist, dass das auch möglicherweise zweifelhaft ist, aber ich bin mir nicht sicher. Insbesondere ist mir nicht klar, was im folgenden Fall passieren würde:

const int& m(const int& x) { return x; }
//...
const int& r = m(23);

Antworten auf die Frage(2)

Ihre Antwort auf die Frage