Подтвердить что ты не робот

Развлечения с неинициализированными переменными и компилятором (GCC)

В разделе §3.9.1/6 из Стандарта С++ говорится:

Значения типа bool равны либо true, либо false.

Теперь рассмотрим этот код,

void f(bool b)
{
    switch(b) //since b is bool, it value can be either true or false!
    {
        case true: cout << "possible value - true";  break;
        case false: cout << "possible value - false"; break;
        default: cout << "impossible value";
    }
}
int main()
{
    bool b; //note : b is uninitialized
    f(b);
    return 0;
}

Скомпилировать F:\workplace>g++ test.cpp -pedantic

Run. Выход:

невозможное значение

Неожиданный результат? Ну, не совсем так, как в Стандарте говорится в сноске п. 3.1.1/6, что:

Использование значения bool описанными способами настоящим Международным стандартом "undefined," , например , изучив значение неинициализированный автоматический объект, может привести к тому, что он будет вести себя так, как будто он ни true, ни false.

Итак, независимо от того, сколько раз я компилирую и запускаю эту программу, я получаю тот же результат: impossible value. Однако, если я немного изменил его - удалив из рисунка функцию f() и напишу блок switch в main():

int main()
{
    bool b; //note : b is uninitialized
    switch(b) //since b is bool, it value can be either true or false!
    {
        case true: cout << "possible value - true";  break;
        case false: cout << "possible value - false"; break;
        default: cout << "impossible value";
    }
    return 0;
}

Затем я компилирую и запускаю эту программу, я не получаю impossible value как вывод; независимо от того, сколько раз я повторяю это, я никогда не получаю impossible value.

Мне просто интересно узнать, почему это внезапное изменение в поведении неинициализированного bool?

Ну, с точки зрения языка ясно: поведение undefined. Я понимаю это. Я также понимаю, что компилятор свободен делать что угодно. Однако с точки зрения компилятора это кажется мне очень интересным. Что может сделать компилятор (например, GCC) в каждом случае и почему?

Я использую: g++ (GCC) 4.5.0 - MinGW, on Windows 7 Basic, 64-bit OS.

4b9b3361

Ответ 1

Мне просто интересно узнать, почему это внезапное изменение в поведении неинициализированного bool?

Разберите код и посмотрите, что делают компиляторы.

Мое предположение: поскольку значение теперь используется только локально, компилятор полностью его оптимизирует. Поскольку поведение undefined в любом случае, компилятор может смело предположить какое-либо значение, например. false. Это довольно очевидная оптимизация, так как значение b является постоянным по отношению к компилятору, а вся логика switch избыточна. Итак, зачем помещать его в исполняемый файл?

(Важным моментом здесь является то, что b используется только когда-либо локально во втором коде, что, в свою очередь, вызовет больше оптимизаций даже в неоптимизированном коде. Первый код должен быть встроен до того, как компилятор сможет сделать такие оптимизации, или трассировки кода, которые не являются тривиальными).