Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `C == C++` undefined behaviour?

A friend tells me that after:

int C = anything;

C == C++ will have the value true. This is intended as a joke, a rebuttal of sorts to the oft-claimed "C is not the same as C++".

However, since == is not a sequence point, I argue that this is in fact undefined behavior. The program may first evaluate C++, so that C > C++ and C == C++ are both undefined. However, C >= C++ will always evaluate as true. The same, of course, is true when the operands are flipped (C++ <= C is always true and everything else is undefined).

Is this analysis correct?

like image 492
Fengyang Wang Avatar asked Sep 22 '14 00:09

Fengyang Wang


1 Answers

All cases lead to undefined behavior and unpredictable results.

The draft C++11 standard tells us that unless stated otherwise the order of evaluations of operands are unsequenced and if the same scalar object is modified more that once by unseqeucend side effects than we have undefined behavior. It is also undefined if we need modify the object and have to compute the value of the object for another operand. This is covered in the draft C++11 standard section 1.9

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

Neither the equality operators or relational operators in sections 5.9 Relational operators and 5.10 Equality operators specify a sequencing for the operands.

clang also provides a warning for this case, it looks like by default, it should something similar to the following (see it live):

 warning: unsequenced modification and access to 'C' [-Wunsequenced]
  if( C == C++ )
      ~     ^

This is also undefined behavior in C++03 with did not use the concept of sequencing relationships but just sequence points. In the draft C++03 standard the relevant section would be Chapter 5 Expressions which says:

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.57) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

which is simpler to reason about since multiple modification of or a modification and use of the value of a scalar within the same sequence point is undefined behavior without having to figure out the sequencing of operations.

like image 137
Shafik Yaghmour Avatar answered Sep 30 '22 12:09

Shafik Yaghmour