2

Consider the following code:

#include <string>
#include <iostream>

int f(int n)
{
    int i = 0;
    for (i = 0; n < 0 || n > 0; n *= 2, ++i) {
        std::cout << "n = " << n << std::endl;
    }
    return i;
}

int main(int argc, char* argv[])
{
    return f(argc > 1 ? std::stol(argv[1]) : 1) != 0;
}

On clang++ it outputs:

n = 1
n = 2
n = 4
n = 8
n = 16
n = 32
n = 64
n = 128
n = 256
n = 512
n = 1024
n = 2048
n = 4096
n = 8192
n = 16384
n = 32768
n = 65536
n = 131072
n = 262144
n = 524288
n = 1048576
n = 2097152
n = 4194304
n = 8388608
n = 16777216
n = 33554432
n = 67108864
n = 134217728
n = 268435456
n = 536870912
n = 1073741824
n = -2147483648
n = 0

On g++5 and g++6 it outputs:

n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
n = 0
...

Which is... an interesting behavior. What is happening? Is it a compiler bug?

Vincent
  • 57,703
  • 61
  • 205
  • 388

1 Answers1

1

Unless the program is called with argument 0, the function f gets called with a non-zero argument.

The loop iteration step n *= 2 will eventually cause integer overflow, which is undefined behaviour. This is a bug in the program, not a bug in the compiler.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • @Vincent It means literally anything can happen ; the example "demons may fly out your nose" used to be commonly used – M.M Jul 24 '17 at 00:10
  • I presume the compiler has determined that n will overflow (due no other exit conditions from loop), and therefore will generate the undefined behavior at some time in the future. When n * 2 (e.g n=1) does not overflow, is the compiler valid to invoke undefined behavior as the result of 1*2 is not undefined? So yes, the program has a bug, but does the compiler also have one? If a compiler can determine undefined behavior will happen in a program, is it allowed to invoke the undefined behavior before the event that generates it actually occurs? – mattnz Jul 27 '17 at 23:12
  • 1
    @mattnz "undefined behaviour" is a property of the program, it's not something the compiler has to invoke. (If the compiler could always detect UB then there would be no need to have the concept of UB!). [This thread](https://stackoverflow.com/questions/29855620/can-undefined-behavior-which-would-follow-a-getc-alter-program-behavior-if-the) may answer your question – M.M Jul 28 '17 at 01:39