Heim >Backend-Entwicklung >C++ >Ist „i = i;' auch bei benutzerdefinierten Typen ein undefiniertes Verhalten?
Undefiniertes Verhalten und Sequenzpunkte: Ein tieferer Einblick
Der Ausdruck i = i; wurde als Aufruf undefinierten Verhaltens (UB) gekennzeichnet, aber was ist, wenn der Typ von i benutzerdefiniert ist, wie in der bereitgestellten Indexklasse?
Benutzerdefinierte Typen und UB
Bei benutzerdefinierten Typen wie Index ist der Ausdruck i = i; gilt immer noch als UB. Dies liegt daran, dass der benutzerdefinierte Typ das Standardverhalten der Inkrementoperatoren nicht überschreibt. Die Funktionen „operator ()“ und „operator =()“ ändern nur den internen Status des Indexobjekts und erstellen keine Sequenzpunkte. Daher ändert der Ausdruck das Objekt zweimal zwischen aufeinanderfolgenden Sequenzpunkten, was zu UB führt.
Äquivalenz von Ausdrücken
Die Ausdrücke i.operator =(i.operator () ); und i.add(i.inc()); sind nicht äquivalent zum Original i = i;. Im ersten Ausdruck ermöglicht der Sequenzpunkt nach der Auswertung von i.operator() die Änderung des Indexobjekts vor der Auswertung des =-Operators. Ebenso verändern im zweiten Ausdruck die Mitgliedsfunktionen add und inc das Objekt zwischen aufeinanderfolgenden Sequenzpunkten nicht. Daher rufen diese Ausdrücke kein UB auf.
Ausdrucksdefinition und Sequenzpunkte
Der Ausdruck i = i; ist zwar ein Ausdruck, aber sein Verhalten ist nicht genau definiert. Die Anzahl der mit einem Ausdruck verknüpften Sequenzpunkte hängt nicht von der Art der beteiligten Operanden ab.
Array-Subskription (a[ i] = i)
Der Ausdruck a [ ich] = ich; ist auch UB in beiden Fällen, wenn a ein Array eines integrierten Typs ist oder wenn a ein benutzerdefinierter Typ ist, der den Indexoperator überlädt. In beiden Fällen wird zuerst der Ausdruck [i] ausgewertet, der i inkrementiert und seinen vorinkrementierten Wert zurückgibt. Dieser Wert wird dann als Index im Array verwendet, was zu UB führen kann, wenn der Index außerhalb der Grenzen liegt.
Mehrere Inkrementierungsoperationen (i)
Der Ausdruck i; ist in C 03 wohldefiniert und hat das gleiche Verhalten wie der Ausdruck ((((i.operator ()).operator ()).operator ()).operator ()).operator ());. Jeder Aufruf des Operators () gibt einen Verweis auf das Indexobjekt zurück, und die Sequenzpunkte nach jeder Funktionsauswertung stellen sicher, dass das Objekt nur einmal zwischen aufeinanderfolgenden Sequenzpunkten geändert wird.
Fazit
Zusammenfassend sind die Ausdrücke i = i; und a[ i] = i; Rufen Sie UB für benutzerdefinierte Typen auf, auch wenn die Typen überladene Operatoren bereitstellen. Mehrere Inkrementoperationen für Indexobjekte sind gut definiert und zeigen, dass Sequenzpunkte und die Anzahl der Änderungen an einem Objekt zwischen Sequenzpunkten unabhängig von der Art der beteiligten Operanden sind.
Das obige ist der detaillierte Inhalt vonIst „i = i;' auch bei benutzerdefinierten Typen ein undefiniertes Verhalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!