Ich lese denken in C++ Kapitel 6 Initialisierung & Bereinigung. Der Autor sagte, dass:Speicherzuweisung in C++
Es ist eigentlich wahrscheinlicher, dass der Compiler der Praxis in C von Zuteilung aller Speicher für einen Bereich an der Öffnung Klammer des dass Umfangs folgen. Es spielt keine Rolle, denn als Programmierer können Sie nicht auf den Speicher zugreifen, bis er definiert wurde. Obwohl der Speicher am Anfang des Blocks zugewiesen ist, tritt der Konstruktoraufruf nicht vor dem Sequenzpunkt auf, an dem das Objekt definiert ist, da der Bezeichner erst dann verfügbar ist. Der Compiler überprüft sogar stellen Sie sicher, dass Sie die Objektdefinition nicht dort setzen, wo die Sequenz Punkt nur bedingt durchläuft, wie in einem Schalter Anweisung oder irgendwo ein Goto kann darüber überspringen.
Und dann der Autor gibt ein Beispiel, wie folgend:
class X {
public:
X();
};
X::X() {}
void f(int i) {
if(i < 10) {
//! goto jump1; // Error: goto bypasses init
}
X x1; // Constructor called here
jump1:
switch(i) {
case 1 :
X x2; // Constructor called here
break;
// case 2 : // Error: case bypasses init
X x3; // Constructor called here
break;
}
}
int main() {
f(9);
f(11);
}///:~
Ich verstehe nicht, warum der obige Code in Ordnung ist? Nach meinem Verständnis, x2
kann Initialisierung umgangen werden, wenn i
nicht 1
ist.
Supplement: „It'a eigentlich wahrscheinlicher, dass der Compiler der Praxis in C von Zuteilung aller Speicher für einen Bereich an der Öffnung Klammer dieses Bereichs folgen“
Dieser Satz verwirrte mich auch.
Laut der Beschreibung des Autors hat der Compiler bei der Eröffnung der switch
bereits Platz für x2
und reserviert. Wenn dies der Fall ist, besteht die Möglichkeit, dass x2
nicht initialisiert wird (Fall 1 ist nicht erfüllt).
Diese Regel war in C++ 03 und wahrscheinlich C++ 98. Und es bricht C-Code nicht, weil alle C++ - Standards eine Ausnahme bei der Initiierung zulassen lized Objekt hat einen C-kompatiblen Typ. – aschepler
Ich bin mir nicht sicher, was Ihren Kommentar zum "Brechen von C-Code" hervorruft? Ja, intrinsics (PODs, ich bin mir nicht sicher, gerade jetzt) sind ein anderes Biest. in der ganzen Sprache. Und, ja, wie ich explizit zeige, waren die Regeln bezüglich Sprünge hinter Initialisierer laxer vor C++ 11 – sehe
C.1 handelt von Unterschieden zwischen C und C++, nicht von Unterschieden zwischen C++ 03 und C++ 11. C++ 11 C.1.5 ist keine Änderung; es ist identisch mit C++ 03 C.1.4. Sie scheinen über die Änderung zu 6.7p3 zu sprechen, die ja einige C++ 03 Code bricht. – aschepler