Печать нуля, но не выход из цикла на основе этого условия


Рассмотрим следующий код:

#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;
}

На clang++ выводит:

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

На g++5 и g++6 он выводит:

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
...

То есть... интересное поведение. Что происходит? Это ошибка компилятора?

1   2  

1 ответ:

Если программа не вызывается с аргументом 0, функция f вызывается с ненулевым аргументом.

Шаг итерации цикла n *= 2 в конечном счете вызовет переполнение целого числа, которое являетсянеопределенным поведением . Это ошибка в программе,а не в компиляторе.