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