Heim >Backend-Entwicklung >C++ >Ruft „i = i' undefiniertes Verhalten mit benutzerdefinierten Typen in C auf?

Ruft „i = i' undefiniertes Verhalten mit benutzerdefinierten Typen in C auf?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-05 10:36:15817Durchsuche

Does `i  =   i` Invoke Undefined Behavior with User-Defined Types in C  ?

Undefiniertes Verhalten überarbeitet: Sequenzpunkte und benutzerdefinierte Typen

Die Frage:

In einem früheren Teil über undefiniertes Verhalten und Sequenzpunkte wurde davon ausgegangen, dass der Ausdruck i = i undefiniertes Verhalten für hervorruft eingebaute Typen. Es stellt sich jedoch die Frage: Was ist, wenn der Typ von i benutzerdefiniert ist? Nehmen wir insbesondere an, wir haben einen Klassenindex mit überladenen Operatoren.

Die Antwort: Undefiniertes Verhalten vs. wohldefiniertes Verhalten

Im Gegensatz zur Intuition stellt sich heraus, dass die Ausdruck i = i ruft kein undefiniertes Verhalten für benutzerdefinierte Typen wie Index auf. Dies liegt daran, dass die überladenen Operatoren im Index als Funktionen betrachtet werden. Gemäß dem C-ISO-Standard führt die Funktionsauswertung einen Sequenzpunkt nach der Auswertung der Funktionsargumente und einen weiteren nach dem Kopieren des zurückgegebenen Werts ein.

Sequenzpunkte und überladene Operatoren

Im Fall von i = i wird der Ausdruck i ausgewertet, bevor er als Argument an den Operator = übergeben wird. Dies bedeutet, dass es nach der Auswertung von i einen Sequenzpunkt gibt, der sicherstellt, dass das Objekt i zwischen aufeinanderfolgenden Sequenzpunkten nur einmal geändert wird.

Daher ist der Ausdruck i = i für benutzerdefinierte Typen wie Index äquivalent zum Schreiben von i.operator =(i.operator ());, einem wohldefinierten Ausdruck ohne undefiniertes Verhalten. Das Gleiche gilt für den syntaktisch einfacheren Ausdruck i.add(i.inc());.

Eine subtile Unterscheidung:

Es ist wichtig zu beachten, dass i = i ist kein Ausdruck im Sinne der C-Grammatik. Stattdessen handelt es sich um einen „Anweisungsausdruck“, also eine syntaktische Kombination aus einem Ausdruck und einer Anweisung. Anweisungsausdrücke werden wie normale Anweisungen ausgeführt, ihr Ergebnis kann jedoch auch einer Variablen zugewiesen werden.

Verhalten von a[ i] = i

Wenn a ein Array ist eines integrierten Typs ruft der Ausdruck a[ i] = i undefiniertes Verhalten auf, da der L-Wert a[ i] zweimal ausgewertet wird: einmal im Ausdruck i und noch einmal in der Zuweisung i = i.

Wenn a jedoch ein benutzerdefinierter Typ ist, der den Indexoperator überlädt, kann sich der Ausdruck je nach Implementierung des Indexoperators unterschiedlich verhalten. Wenn der Indexoperator beispielsweise mit const Index& Operator[](Index i) implementiert wird, ist der Ausdruck wohldefiniert, da der L-Wert a[ i] nur einmal ausgewertet wird, bevor der Indexoperator aufgerufen wird.

Die Gültigkeit von i;

Der Ausdruck i; ist in C 03 wohldefiniert, da es äquivalent zu ((i.operator ()).operator ()).operator () ist. Dies liegt daran, dass jeder Operator einen Sequenzpunkt einführt und so sicherstellt, dass das Objekt i zwischen aufeinanderfolgenden Sequenzpunkten nur einmal geändert wird.

Das obige ist der detaillierte Inhalt vonRuft „i = i' undefiniertes Verhalten mit benutzerdefinierten Typen in C auf?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn