-2

I am getting output as 0..0 in the below given program.Why does j doesn't get incremented while if condition is being checked?

int main(int argc, char const *argv[])
{
    int i=0,j=0;

    if(i&&j++)  
        printf("%d..%d",i++,j);
    printf("%d..%d",i,j);
    return 0;
}
Rahul Gusai
  • 701
  • 1
  • 6
  • 11

4 Answers4

8

Since i is zero the second half of the if doesn't need to be evaluated so j++ never occurs.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
cleblanc
  • 3,678
  • 1
  • 13
  • 16
1

A post-increment, not surprisingly, will only happen after the statement and it will only happen if that part of the expression was evaluated.

Don't forget that conditions on the right side of && are only evaluated if the left side passes. The j++ part of that statement never gets evaluated because i is 0.

What your code translates to is roughly:

if (i) { // Always 0, so the inner block is skipped.
  if (j) {
    j = j + 1;
    // ...
  }
  else {
    j = j + 1;
  }
}

If these sorts of operations are confusing, it's alright to steer away from them entirely. Even experienced programmers can get tripped up on them. When you presume too much and write code like j + j++ you're going to end up in trouble.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 3
    `j` doesn't get incremented at all. –  Dec 12 '17 at 20:18
  • @Ivan Good catch. Updated accordingly. – tadman Dec 12 '17 at 20:19
  • @Yashas Rephrased and used a long-form version of code to better explain. – tadman Dec 12 '17 at 20:22
  • Not only does `j` not get incremented, *it doesn't even get checked*, contrary to your first paragraph. – John Bollinger Dec 12 '17 at 20:24
  • @JohnBollinger I'm tossing a bunch of verbiage here that wasn't quite clear enough. – tadman Dec 12 '17 at 20:27
  • @Yashas So the precedence rule doesn't apply here according to which inside the parenthesis, right side of the && should be evaluated first ? – Rahul Gusai Dec 12 '17 at 20:33
  • @RahulGusai It's left to right in most cases according to the usual [operator precedence](http://en.cppreference.com/w/c/language/operator_precedence) rules. – tadman Dec 12 '17 at 20:34
  • @Yashas No but precedence of postfix operator is higher than &&, right ? – Rahul Gusai Dec 12 '17 at 20:35
  • @RahulGusai Atomic operators like `++` and `!` usually are. Binary operators like `&&` are not obligated to execute on both sides, things like `j++` or function calls can be skipped. Postfix `++` is actually the highest precedence. – tadman Dec 12 '17 at 20:39
  • Post-increment changes the value of the operand before the next sequence point, not after the statement is executed. – Eric Postpischil Dec 12 '17 at 20:41
  • 1
    @RahulGusai: Precedence determines how the parts of an expression are grouped. It does not determine execution order. For many operators, like `+` and `*`, the compiler may evaluate either side first and may even do parts of one, then parts of the other, and so on. For `&&`, the compiler is required to evaluate the left side first (or at least not to let the right side have any final effect until the left side is done) and is required not to evaluate the right side if the left side is false. C has rules about sequence points that affect execution order. – Eric Postpischil Dec 12 '17 at 20:49
1

In the statement:

if(i&&j++)  

i has the value 0 so even if the j were pre-incremented it would not be evaluated. The && and || operators short-circuit , that is they quit as soon as an answer is known,. I the case of && that is the left side evaluating to zero, in the case of || it is the left side evaluating to non-zero.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
0

Expressions involving the logical AND operator can be rewritten as follows:

if(expr1 && expr2 && expr3 ...)

is functionally equivalent to

if(expr1)
    if(expr2)
        if(expr3)
        .
        .
        .

If expr1 fails, the remaining won't be evaluated.

If expr1 succeeds, expr2 will be evaluated and if expr2 fails, expr3 won't be evaluated.

In your case i is zero, hence j++ won't be evaluated.


Excerpt from Section 6.5.13 C99 specifications

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

Yashas
  • 1,154
  • 1
  • 12
  • 34