Розглянемо цей простий код:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
Ви бачите, що gcc
ні clang
оптимізуйте потенційний дзвінок g
. Це правильно в моєму розумінні: абстрактна машина передбачає, що volatile
змінні можуть змінюватися в будь-який момент (через те, що, наприклад, апаратне відображення), тому постійне складання false
ініціалізації в if
чек було б неправильним.
Але MSVC повністю виключає виклик g
(зберігаючи читання та запис, volatile
хоча!). Це поведінка, що відповідає стандартам?
Передумови: Іноді я використовую такий тип конструкції, щоб мати змогу вмикати / вимикати налагоджувальний вихід на ходу: компілятор повинен завжди читати значення з пам'яті, тому зміна цієї змінної / пам'яті під час налагодження повинна відповідно змінювати потік управління . Вихід MSVC перечитує значення, але ігнорує його (імовірно, через постійне складання та / або усунення мертвого коду), що, звичайно, перемагає мої наміри тут.
Зміни:
Усунення читання та запису
volatile
обговорюється тут: Чи дозволяється компілятору оптимізувати локальну змінну змінну? (дякую Натане!). Я думаю, що стандарт цілком зрозумілий, що ті, хто читає і пише, повинні відбуватися. Але ця дискусія не стосується того, чи законно компілятор приймати результати цих прочитаних як належне та оптимізувати на основі цього. Я припускаю, що це є недостатньо визначеним у стандарті, але я був би радий, якби хтось довів мене неправильно.Я, звичайно, можу зробити
x
не локальну змінну, щоб побіжно перейти до проблеми. Це питання більше викликає цікавість.