Pergunta

I have compiled the code below in codeblocks and it shows the output 0...0 . But I think its output should be 0...1 because "if" statement is not true here so the statement following the "if" is not executed.Then j is incremented by 1 ( because of j++ in "if" statement ) but i remains 0. So , the last printf() should give 0...1 .

#include <stdio.h>

int main()
{
    int i =0,j=0;
    if(i && j++)
        printf("%d..%d\n",i++,j);
    printf("%d...%d",i,j);
    return 0;
}
Foi útil?

Solução

See C11 6.5.13 Logical AND operator p4 (my emphasis)

Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares equal to 0, the second operand is not evaluated.

The first operand in your example is i. It compares equal to 0 so the second operand (j++) is not evaluated (executed). It is therefore correct that your later printf shows that j is still 0.

Outras dicas

Since i is 0 (falsy), there's no reason to execute j++. It's called short circuit.

It's useful in checks like if(a < v.size() && v[a] == 5) // do something

the first part of the condition (i) is already false so the second part (j++) is not executed.

You won't get to incrementing j. Look at your if statement:

if(i && j++)

You only execute the if block when both i AND j are true. But since i is already false there's no need to even check j++. It's also called Short-circuit evaluation.

The reason the increment to j in the if condition is not being applied is because that expression is being short-circuited--i.e., i is never non-zero, so the second expression need not be evaluated.

Instead of using logical-and &&, use bitwise-and &, which will not short circuit and work the way you want as long as i and j are 0 or 1:

...
if(i & j++)
    printf("%d..%d\n",i++,j);

or if they're not:

if (!!i & !!(j++))
   ...

the j++ expression is not executed because the evaluation of the first condition i (left side of the && operator) already returns false so, the second condition j++ is not evaluated.

This is a common optimization made by the compiler, usually called short circuit condition evaluation, in some compilers you may turn off this optimization, to avoid this kind of side effect.

as you see in this example code, from your source second IF is not executed :

    movl    i(%rip), %eax       
    testl   %eax, %eax          ; <-- if i
    je  .L2
    movl    j(%rip), %eax
    testl   %eax, %eax          ; <-- if j Not EXECUTED !!!
    setne   %dl 
    addl    $1, %eax            ; <-- j++
    movl    %eax, j(%rip)
    testb   %dl, %dl
    je  .L2
    ...                         ; inner IF
.j2

as explained in the other answer.

As you mentioned that if statement is false is true. But i believe the concept/logic used is somewhere inappropriate, the reason will follow.

Before that lets understand the working of &&(Logical AND) operator. If states that if both the operands associated with it are true then only the result is true. NOTE: 1. for the compiler it means that if any one operand is false that the compiler will not compute further i.e. skip to next valid line of code. 2. 0(zero) states to false - in programming.

Well, Compiler at the first go search for the operator and then look for the operands which are associated with it.

So, as soon as the compiler encounter '&&' it will look at the left side of the operator as the associativity of &&(Logical AND) is left-to-right and evaluate the value for the operand on the left which is 0(zero). Now, refer the note 2 and then 1.

Hence, the compiler jump to the next valid statement which is printf("%d...%d",i,j);

Here, no increment was made to variable 'j", therefore the value of "j" will remain 0(zero).

NOTE: To further get clear with the idea, I would suggest to try the same example with different values of i and j, like i=1 and j=1 or i=2 and j=1.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top