Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

complicated expression involving logical AND (&&)

void main(void)
{
  int x,y,z;
  x=y=z=1;

  z = x && y && ++z;//is this fine?
}

I have lately started reading about sequence points stuffs but I cannot figure out whether the above sample of code is fine or not. I know the && operator introduces a sequence point so I am not very sure about the behavior of the expression z = x && y && ++z. Someone please tell me the correct answer.

like image 909
Rajan Chaubey Avatar asked Oct 03 '10 14:10

Rajan Chaubey


2 Answers

In C++ 03.

void main(void) 
{ 
  int x,y,z; 
  x=y=z=1;                                  // Seq1 at ;

  z = x && y && ++z;//is this fine?         // Seq2 at ;
} 

NB: Note that there are sequence points at the operator && but then those are not relevant in this example.

Fine!. In general, may be or may be Not. Depends on the values of x and y. In your specific case, it is not fine. This code has the potential to have something called undefined behavior.

If z++ is evaluated (as in your example because x and y are 1), then the scalar variable 'z' is modified more than once in the expression between two sequence points Seq1 and Seq2 (see below). It is important to note that the assignment operator does not introduce any sequence point.

$5/4- "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.53) 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."

In C++0x

Will update it once I myself understand the details of the discussion referred to by @litb. For now, I am just striking it off

In C++0X however, as I understand, there is no concept of sequence points. This expression is fine and does not invoke undefined behavior. This is because the effect of ++ on 'z' is sequenced before the side effect of assignment on 'z'.

$1.9/15- "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.

$3.9/9 - "Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_t, and cv-qualified versions of these types (3.9.3) are collectively called scalar types."

Note that in the expression 'z = z++;' where z is a scalar variable, the side effects on 'z' due to assignment operator and postfix operator++ are unsequenced (neither of them is sequenced before the other).

Thanks @Prasoon for giving valuable inputs to refine this post from original version

like image 197
Chubsdad Avatar answered Oct 24 '22 16:10

Chubsdad


A simple way to know if that line is fine or not is let the compiler check that. For example, gcc has the -Wsequence-point option (enabled by -Wall) for checking if there's undefined behavior because of lack of sequence points.

Your program

int main(void)
{
  int x,y,z;
  x=y=z=1;

  z = x && y && ++z;/*is this fine?*/

    return 0;
}

produces this warning:

x.c: In function 'main':
x.c:6:5: warning: operation on 'z' may be undefined
like image 45
kennytm Avatar answered Oct 24 '22 17:10

kennytm