4

Possible Duplicate:
Is short-circuiting boolean operators mandated in C/C++? And evaluation order?

AFAIK Short circuit evaluation means that a boolean expression is evaluated only up to the point that we can guarantee its outcome.

This is a common idiom in perl where we can write things like: (is_ok() returns non-zero value on "OK")

is_ok() || die "It's not OK!!\n";

instead of

if ( ! is_ok() ) {
    die "It's not OK!!\n";
}

This only works because the order of evaluation is always left-to right and that guarantees that the rightmost statement is only executed if the first statement if not "false".

In C I can do something simillar like:

struct foo {
    int some_flag;
} *ptr = 0;

/* do some work that may change value of ptr */
if ( 0!=ptr && ptr->some_flag ) {
    /* do something */
}

Is it safe to use this kind of idiom?

Or is there any chance that the compiler may generate code that evaluates ptr->some_flag before making sure that ptr is not a zero pointer? (I am assuming that if it is non-null it points to some valid memory region).

This syntax is convenient to use because it saves typing without losing readability (in my opinion anyway). However I'm not sure if it is entirely safe which is why I'd like to learn more on this.

NB: If the compiler has an effect on this, I'm using gcc 4.x

Community
  • 1
  • 1
amso
  • 514
  • 1
  • 6
  • 14

4 Answers4

7

The evaluation order of short-circuit operators (|| and &&) is guaranteed by the standard to be left to right (otherwise they would lose part of their usefulness).

§6.5.13 ¶4

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.

§6.5.14 ¶4

Unlike the bitwise | 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 unequal to 0, the second operand is not evaluated.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
4

Or is there any chance that the compiler may generate code that evaluates ptr->some_flag before making sure that ptr is not a zero pointer?

No, zero-chance. It is guaranteed by the standard that ptr->some_flag will not be evaluated if the first operand is false.

6.5.13-4

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.

Community
  • 1
  • 1
cnicutar
  • 178,505
  • 25
  • 365
  • 392
2
/* do some work that may change value of ptr */
if ( 0!=ptr && ptr->some_flag ) {
    /* do something */
}

Is it safe to use this kind of idiom?

Yes.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

It is safe in the above example, however anyone maintaining such code may not realise that there is a dependency on the order of evaluation and cause an interesting bug.

John Beckett
  • 126
  • 2