Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am expecting the answer should come as 1.But in GCC compiler and Turbo c compiler is showing the result as 0.In some DEV c compiler showing the result as 1.Which one is correct and why ?

#include<stdio.h>
int main()
{
   int z = 0;
   z = 0 || z++;
   printf ("%d", z);
   return 0;
 }


What I have tried:

I have tried in Dev c , GCC and Turbo c compiler.
Posted
Updated 2-Mar-17 23:04pm
v2
Comments
Suvendu Shekhar Giri 3-Mar-17 2:48am    
Your question title should not contain code pieces/the whole program.
[no name] 3-Mar-17 3:05am    
->Which one is correct and why ?
Please explain in words the algorithm you are implementing with this code. This code has Undefined behavior[^]

You have a logical Short-circuit evaluation - Wikipedia[^] operation of the form
a || b

The boolean result of the first expression
C++
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:
C++
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):
C++
if (z = 0 || z++)
    printf("true: %d\n", z); // Never reached
else
    printf("false: %d\n", z); // Always executed

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]
 
Share this answer
 
v3
Comments
[no name] 3-Mar-17 3:48am    
->'This should print 0 1 with all compilers.' ?
Jochen Arndt 3-Mar-17 3:58am    
The result of an assignment operation is the value of the left operand after the assignment.
The boolean result is the value being zero or not.
In C++ or C99 with stdbool.h:
bool a = (z = 0); // Always false
bool b = (z = 1); // Always true

[no name] 3-Mar-17 4:13am    
I'm sorry I misread the statement. This is an excellent explanation.
gcc -Wall mytest.c
mytest.c: In function ‘main’:
mytest.c:6:7: warning: operation on ‘z’ may be undefined [-Wsequence-point]
     z = 0 || z++;
That is you hit a dark corner of the C programming language. See, for instance Sequence point - Wikipedia[^].
As a side note, enabling all the warnings (-Wall with gcc may prove itself useful, after all).
 
Share this answer
 
What did you expect from the statements:
C++
int z = 0;
z = 0 || z++;

This is again a question of whether the post-increment is performed before or after the assignment to z.
 
Share this answer
 
Comments
Jochen Arndt 3-Mar-17 3:43am    
It is about short-circuit evaluation and the increment should never be executed.
nv3 3-Mar-17 4:40am    
Hi Jochen! I don't really agree. As the first operand (0) is false, the second operand (z++) must be evaluated and the expression result is always 0.

The actual question is: Will the post-decrement be executed before or after the assignment to z. In the first case, the post-increment to z is executed, then the expression result (0) is assigned to z -- thus overwriting the effect of the post-increment. In the second case, the assignment is first executed, then the post-increment will afterwards increment z to the value of 1.

To my knowledge, the C standard is not clear on the moment on which the post-increment will be executed. And I admit, I personally don't care. Nobody in his clear mind will write a statement like this in production code. Thus, again one of these questions that are purely academic.
Jochen Arndt 3-Mar-17 4:57am    
You are right!
Silly mistake (it is an OR operation).

I will update my solution.
nv3 3-Mar-17 11:12am    
It happens to the best of us :-)
you are in gray zone because C compiler can rewrite your code to optimize.
This line is unpredictable:
C++
z = 0 || z++;

Because you have a postincrement on a variable that is used 2 times in the line.
you get 0 when the code translate to:
C++
tmp = 0 || z;
z++;
z=tmp;

you get 1 when the code translate to:
C++
tmp = 0 || z;
z=tmp;
z++;

It depend on the compiler.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900