12

Why does this code always produce x=2?

unsigned int x = 0;
x++ || x++ || x++ || x++ || ........;
printf("%d\n",x);
3
  • 10
    Smells like someone's homework. Commented Jan 14, 2010 at 19:47
  • 2
    Still a good question, i think. In the first moment, i thought it's undefined behavior. But actually it is not since || is a sequence point between the left and right sides. Commented Jan 14, 2010 at 19:49
  • FYI: en.wikipedia.org/wiki/Sequence_point Commented Jan 14, 2010 at 19:55

10 Answers 10

30

the 1st x++ changes x to 1 and returns 0
the 2nd x++ changes x to 2 and returns 1

at which point the or short circuits, returns true, and leaves x at 2.

Sign up to request clarification or add additional context in comments.

10 Comments

Incidentally: unsigned int x = 0; ++x || ++x || ++x || ++x || ........; printf("%d\n",x); would give 1 as the first ++x would change x to 1 and return x, short-circuiting happens and nothing more is done.
Incidentally, I'm pretty sure this is undefined behavior. Your description of why it would yield 2 is right, but I don't believe it's guaranteed to work that way — you're not supposed to change a variable more than once in a statement The variable could not be incremented until after the whole expression is finished, in which case x would always appear to be 0.
@Chuck: It's defined because || acts as a sequence point. (6.5.14/4 in the C99 standard.)
Cobbal, to make it clearer, you should write your answer as, returns 0 and then changes x to 1. Making it clearing that the expression is incremented post Boolean evaluation.
For the record, sequence points occur at the end of a full expression (initializer, expression statement, the expression in a return statement, and control expressions in conditional, iterative, or switch statements), after the first operand of &&, ||, ?:, or the comma operator, and after the evaluation of the arguments and function expression in a function call.
|
11

x++ || x++ || x++ || x++ || ........;

  • First x++ evaluates to 0 first for the conditional check, followed by an increment. So, first condition fails, but x gets incremented to 1.
  • Now the second x++ gets evaluated, which evaluates to 1 for the conditional check, and x gets incremented to 2. Since expression evaluates to 1 (true), there's no need to go further.

Comments

9

Because of short circuit in boolean expression evaluation and because || is a sequence point in C and C++.

2 Comments

|| is a sequence point, as the page you linked to mentions. So this is not undefined behaviour.
The || operator introduces a sequence point, so the expression is not undefined.
5

|| short-circuits. Evaluated from left, when a true value is found (non-zero) it stops evaluating, since the expression now is true and never can be false again.

First x++ evaluates to 0 (since it's post-increment), second to 1 which is true, and presto, you're done!

Comments

2

When you're evaluating "a || b || c || d || e || ..." you can stop evaluating at the first non-zero value you find.

The first "x++" evaluates to 0, and increments x to 1, and evaluating the expression continues. The second x++ is evaluated to 1, increments x to 2, and at that point, you need not look at the rest of the OR statement to know that it's going to be true, so you stop.

1 Comment

To be precise, you do stop evaluating at the first non-zero value you find.
1

Because logical OR short-circuits when a true is found.

So the first x++ returns 0 (false) because it is post-increment. (x = 1) The second x++ returns 1 (true) - short-circuits. (x = 2)

Prints x = 2;

Comments

1

Because of early out evaluation of comparisons.

This is the equivalent of

 0++ | 1++

The compiler quits comparing as soon as x==1, then it post increments, making x==2

Comments

1

Because the first "x++ || x++" evaluates to "true" (meaning it is non zero because "0 || 1" is true. Since they are all logical OR operators the rest of the OR operations are ignored.

Mike

Comments

1

The || operator evaluates the left-hand expression, and if it is 0 (false), then it will evaluate the right-hand expression. If the left hand side is not 0, then it will not evaluate the right hand side at all.

In the expression x++ || x++ || x++ || ..., the first x++ is evaluated; it evaluates to 0, and x is incremented to 1. The second x++ is evaluated; it evaluates to 1, and x is incremented to 2. Since the second x++ evaluated to a non-zero value, none of the remaining x++ expressions are evaluated.

Comments

0

trying replacing || with |.--

It is the short circuiting of logical operators.

It's the same reason when you do

if (returns_true() || returns_true()){ }

returns_true will only get called once.

1 Comment

Since || is a sequence point and | isn't, if you replace || with |, you'll be invoking undefined behavior, and that won't really tell you anything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.