You have a logical
Short-circuit evaluation - Wikipedia[
^] operation of the form
a || b
The boolean result of the first expression
z = 0
is the value of the left operand
z
after the assignment. When that is zero, the boolean result is false. You can check this:
int z = 0;
int a = (z = 0) ? 1 : 0;
int b = (z = 1) ? 1 : 0;
printf("%d %d\n", a, b);
This should print
0 1
with all compilers.
Once the boolean result of the left term has been evaluated, the second operation should be only executed when the first was true:
int b = (z = 0) ? 1 : 0;
if (b)
b = (z++) ? 1: 0;
Then
z
will be still zero because the increment operation is not executed.
[EDIT2]
The above is wrong (thank you NV)!
It should be off course if
(!b)
[/EDIT2]
So compilers executing always the second operation may be not conforming to the C standard. I wrote "maybe" because I'm not really sure in this special case where the logical result is not used.
You might check it this way (all optimisations disabled; e.g. -O0 with GCC):
if (z = 0 || z++)
printf("true: %d\n", z); else
printf("false: %d\n", z);
A compiler that prints "1" here is not conforming to the C standard.
[EDIT]
Note also that optimising compilers might detect that the result of the logical operation is always false and assign zero to
z
or even skip the line
z = 0 || z++;
because
z
has been already set to zero in the previous line.
[/EDIT]
[EDIT2]
Solution 3 is pointing out the problem.
The behaviour is undefined as indicated by the warning.
Try this:
int z = 0;
z = 0 || z++;
printf ("z: %d\n", z);
(z = 0) || (z++);
printf ("z: %d\n", z);
With GCC, it will print
z: 0
z: 1
[/EDIT2]