3

For C++03, the standard says, that between left and right operand of && operator there is a sequence point, so that all side effects of left operator have taken place before right operator is accessed.

So

int i = 0;
if (++i && i--)
    std::cout << i;

is well defined and is guaranteed to output 0.

But what is about this question: is right operand only evaluated if left operand is not 0? It seems to be a detail, but to me the standard guarantees only the sequence point between the operands, not that right operand is never evaluated/accessed in dependence of left one.

E.g.

int arr[10];
int pos; // somehow set to a value from 0 to 10
while (pos < 10 && arr[pos] != 0)
    pos++;

Is this well defined? pos could be from begin on 10 or reaches 10. The left operand has no side effects which concur with right operand. Have I the guarantee that arr[10] != 0 is never performed?

Edit:

Thanks to the comments and answers it is clear now:

5.14p2: "The result is a bool. If the second expression is evaluated,
every value computation and side effect associated with the first expression
is sequenced before every value computation and side effect associated with
the second expression."

is the sequence point meaning.

5.14p1: "Unlike &, && guarantees left-to-right evaluation: the second operand is
not evaluated if the first operand is false."

is the short-circuit meaning.

The first without the second would make my example undefined. Thanks.

mb84
  • 683
  • 1
  • 4
  • 13
  • 1
    "*The standard says, that between left and right operand of && operator there is a sequence point,*". **I doubt**. Could you quote the actual text? – Nawaz Jan 20 '14 at 16:16
  • @Nawaz http://en.wikipedia.org/wiki/Sequence_point – Luchian Grigore Jan 20 '14 at 16:17
  • @Nawaz: depends on version, doesn't it? C++03 would have said "sequence point", C++11 will say "sequenced before". – Steve Jessop Jan 20 '14 at 16:18
  • @LuchianGrigore: What is that? Wiki page? Does it answer my question? – Nawaz Jan 20 '14 at 16:19
  • 1
    5.14p2: "The result is a bool. If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression." – godel9 Jan 20 '14 at 16:19
  • IMO: It would be more of a head-scratcher as `if (i++ || --i)` – WhozCraig Jan 20 '14 at 16:20
  • I'm curious: where did you get the impression that the standard *doesn't* specify that the right operand is evaluated only if necessary? – Keith Thompson Jan 20 '14 at 16:21
  • 1
    @LuchianGrigore: Wikipedia is not the standard. – Keith Thompson Jan 20 '14 at 16:22
  • I read it here http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points and some other sources. I don't have a copy of the standard. @ Keith Thompson : I think of a sequence point being a point, where further evaluation waits for side effects to be completed. Not a point where further evaluation depends on value of preceding evaluation. So saying only that there is a sequence point between `x && y` is not enough. But according to the answers, the standard seems explicitely to guarantee non-evaluation of y in dependence of value of x. So it's more than a seqence point. – mb84 Jan 20 '14 at 16:37
  • @mb84: Yes, the sequence point and the conditional evalution of the right operand are distinct rules -- both stated clearly in the language standard. Drafts of the C++ standard are freely available through the [committee's web site](http://www.open-std.org/JTC1/SC22/WG21/) (I'm not sure which draft is the most current). – Keith Thompson Jan 20 '14 at 19:40
  • @Nawaz: C++03 §1.9/18 “In the evaluation of each of the expressions [vertical list of] `a && b`, `a || b`, `a ? b : c`, `a , b`, using the built-in meaning of the operators in these expressions (5.14, 5.15, 5.16, 5.18), there is a sequence point after the evaluation of the first expression 12)” – Cheers and hth. - Alf Dec 06 '17 at 05:47

2 Answers2

9

The standard does guarantee short-circuiting of && and ||.

If the left-hand side of && is false, the right-hand side is not evaluated. For ||, the right-hand side is not evaluated if the left-hand side is true.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Thank you too. I accepted the other answer, because citing the standard, although yours is saying the same + analogously for `||`... Upvote. – mb84 Jan 20 '14 at 17:06
5

5.14p1 of C++11, last sentence:

Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

So yes, it's guaranteed.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • 1
    I'd suggest adding paragraph 2 as well, since there seems to be some confusion in the comments about sequencing and side effects. – godel9 Jan 20 '14 at 16:20
  • 1
    @mb84: The wording and paragraph number are identical in C++03. – Mike Seymour Jan 20 '14 at 16:24
  • 5.14p1 of the 1998 and 2003 editions of the ISO C++ standard say exactly the same thing. – Keith Thompson Jan 20 '14 at 16:25
  • @godel9 Where can I read paragraph 2? So this cited sentence is more than a sequence point?! Evaluation of second operand not only waits for side effects of first one to take place, its "happening" also depends of value of first operand. – mb84 Jan 20 '14 at 16:43
  • @mb84 I posted paragraph 2 in the comments to your question. – godel9 Jan 20 '14 at 16:49
  • @godel9 Ok, so 5.14p2 is the sequence point meaning and 5.14p1 is the little "extra" to it. This was the detail I was searching. Thanks. – mb84 Jan 20 '14 at 16:52
  • @KeithThompson Although I don't have my copy of K&R I handy to verify, I'm pretty sure it said basically the same thing. (Probably in different words. I don't think K&R I spoke of sequence points.) – James Kanze Jan 20 '14 at 19:15