## C/C++ Gotcha – Conditional Evaluation

Posted: 28th December 2010 by Tim in C, C++
Tags: , , , , , , , ,

C and C++ code is generally pretty easy to make sense of. But there are a few oddities which can catch you out and can send you into an endless debugging exercise if you’re not careful. One such oddity is conditional evaluation.

Consider the following code which keeps track of three numbers. Look through the code and try to guess what will be printed at the end of the program.

`#include <stdio.h>`

```int main() {     int x = 0;     int y = 0;     int z = 0;```

```    while(x++ < 5 || y++ < 5)     {         z++;     }```

`    printf("x: %d\ny: %d\nz: %d\n", x, y, z);`

```    return 0; }```

You would think that the line `while(x++ < 5 || y++ < 5)` would only execute five times, meaning that `z` will equal 5, right? Wrong!

```x: 11 y: 6 z: 10```

So what’s going on here? Well to make the program run faster, the code will only evaluate conditions if it needs to. When this code is first run, `x` is 0 and therefore `x++ < 5` is `true`. It now doesn’t matter whether `y++ < 5` is `true` or not, because `true` OR’d with anything is always `true`. So `y` is not evaluated and therefore not incremented. Until `x` is 5.

When `x = 5`, the first part of this conditional will be `false` and `y` will start to be incremented. The loop will therefore be run another five times, resulting in `z` equalling 10.

Confusing? At first, yes. It just takes a bit to get your head around. In general, don’t change the program state in a conditional block like that unless it’s the first (or only) condition, or you know what you’re doing. And even if you know what you’re doing, try to avoid these things or your code may become unmanageable.

1. nh2 says:

Gotcha? Yes, you did got me…
Great example. And it also works in Java.

2. […] parcourant un blog dont j’ai trouvé le lien dans Stack Overflow, je suis tombé sur exemple de code en C […]

3. Chris says:

You can also use this to your advantage, only evaluating the latter if the former succeeds:
if (OpenFile() && ReadFromFile() && CloseFile()) Log(“File has been written”);
else Log(“Error writing to file”);

Or:
if ((x != nullptr) && !x->DoSomething()) …