Разрешено ли это преобразование компилятора?

Рассмотрим этот код, где x а также y целые числа:

if (x)
    y = 42;

Разрешено ли следующее преобразование компилятора?

int tmp = y;
y = 42;

if (!x)
    y = tmp;

контекст:

Это из часто задаваемых вопросов Бьярна Страуструпа:

// start with x==0 and y==0

if (x) y = 1;   // Thread 1 

if (y) x = 1;   // Thread 2

Часто задаваемые вопросы утверждают, что это гонка данных бесплатно; с x а также y оба 0, ни один из переменных не должен быть записан.
Но что, если трансформация разрешена?

1 ответ

Решение

В отличие от того, что я написал в своем некорректном комментарии, это преобразование фактически не допускается, если y потенциально разделяется между потоками, и компилятор не может доказать существование существующего UB в исходном коде.

Стандарт прямо говорит:

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

[intro.multithread] (1.10 / 22) в N3337, (1.10/25) в N4141.

Так что если x всегда равно 0, исходный код будет свободен от гонки, а преобразованный - нет. Таким образом, преобразование не является законным.

Если бы это было так, то вы просто не смогли бы исключить доступ к любому объекту, достижимому из глобальных переменных или других переменных. Компилятор может даже предварительно вызывать функции, которые никогда не вызываются, всякий раз, когда делается косвенный вызов, и "отменять" их действие впоследствии, восстанавливая исходное значение.

Пройдя по пути оптимальной пессимизации, он может заранее сделать деление на ноль, а затем "проигнорировать" результат, если делитель был равен нулю, даже если это ловушка и программа остановлена.

Это явно абсурдно и должно быть отвергнуто независимо от того, должно ли это быть согласно стандарту.

Другие вопросы по тегам