Undefined Behavior and Sequence Points: A Deeper Dive
The expression i = i; has been labeled as invoking undefined behavior (UB), but what if the type of i is user-defined, as in the Index class provided?
User-Defined Types and UB
In the case of user-defined types like Index, the expression i = i; is still considered UB. This is because the user-defined type does not override the default behavior of the increment operators. The operator () and operator =() functions only modify the internal state of the Index object and do not create any sequence points. Therefore, the expression modifies the object twice between consecutive sequence points, resulting in UB.
Equivalence of Expressions
The expressions i.operator =(i.operator ()); and i.add(i.inc()); are not equivalent to the original i = i;. In the first expression, the sequence point after the evaluation of i.operator () allows for the modification of the Index object before the evaluation of the = operator. Similarly, in the second expression, the member functions add and inc do not modify the object between consecutive sequence points. Hence, these expressions do not invoke UB.
Expression Definition and Sequence Points
The expression i = i; is indeed an expression, but its behavior is not well-defined. The number of sequence points associated with an expression does not depend on the type of operands involved.
Array Subscripting (a[ i] = i)
The expression a[ i] = i; is also UB in both cases when a is an array of a built-in type or when a is a user-defined type that overloads the subscript operator. In both cases, the [ i] expression is evaluated first, which increments i and returns its pre-incremented value. This value is then used as the index into the array, which may result in UB if the index is out of bounds.
Multiple Increment Operations ( i)
The expression i; is well-defined in C 03 and has the same behavior as the expression ((((i.operator ()).operator ()).operator ()).operator ()).operator ());. Each operator () invocation returns a reference to the Index object, and the sequence points after each function evaluation ensure that the object is modified only once between consecutive sequence points.
Conclusion
In summary, the expressions i = i; and a[ i] = i; invoke UB for user-defined types, even if the types provide overloaded operators. Multiple increment operations on Index objects are well-defined, demonstrating that sequence points and the number of modifications to an object between sequence points are independent of the type of operands involved.
The above is the detailed content of Is `i = i;` Undefined Behavior Even with User-Defined Types?. For more information, please follow other related articles on the PHP Chinese website!