Разрешено ли переупорядочение магазина правилом C++ как-будто?
Правило "как если" в основном определяет, какие преобразования разрешено выполнять реализации в легальной программе на C++. Короче говоря, все преобразования, которые не влияют на наблюдаемое поведение программы, разрешены.
Что касается того, что именно означает "наблюдаемое поведение", то у cppreference.com, кажется, есть другое определение с тем, которое дано Стандартом, относительно ввода / вывода. Я не уверен, является ли это переосмыслением Стандарта или ошибкой.
Правило "как будто" от cppreference.com:
- Все операции ввода и вывода выполняются в том же порядке и с тем же содержанием, как если бы программа была выполнена так, как написано.
Правило "как будто" согласно Стандарту:
- Динамика ввода и вывода интерактивных устройств должна происходить таким образом, чтобы вывод запроса фактически доставлялся до того, как программа ожидает ввода. То, что составляет интерактивное устройство, определяется реализацией
Это различие важно для меня, потому что я хочу знать, является ли нормальное переупорядочение магазина действительной оптимизацией компилятора или нет. Согласно формулировке, хранилище памяти должно принадлежать output operations
это упоминает. Но в соответствии со Стандартом хранилище памяти, похоже, не the output dynamics of interactive devices
, (Что такое интерактивные устройства?)
Пример для подражания.
int A = 0;
int B = 0;
void foo()
{
A = B + 1; // (1)
B = 1; // (2)
}
Современный компилятор может генерировать следующий код для функции foo
:
mov 0x804a018, %eax
movl $0x1, 0x804a018 ; store 1 to B
add $0x1, %eax
mov %eax, 0x804a01c ; store 1 to A
ret
Как видно, магазин в A
переупорядочен с магазином в B
, Соответствует ли это правилу "как будто"? Разрешен ли этот вид переупорядочения Стандартом?
2 ответа
Если cppreference.com не согласен с фактическим текстом стандарта C++, cppreference.com неверен. Единственными вещами, которые могут заменить текст стандарта, является более новая версия стандарта и официальные разрешения отчетов о дефектах (которые иногда сворачиваются в документы, называемые "техническими corrigienda", что является причудливым названием для незначительного выпуска документа). стандарт).
Однако в этом случае вы неправильно поняли, что означает cppreference.com под "операциями ввода и вывода". (Если память служит, этот текст дословно взят из более старой версии стандарта.) Сохранения в памяти НЕ являются операциями вывода. Только запись в файл (то есть любой stdio.h
или же iostream
выходной поток или другой механизм, определяемый реализацией, например дескриптор файла Unix), считается выходным для целей этого правила.
Стандарты C и C++ до их редакций 2011 года предполагали однопоточную абстрактную машину и, следовательно, не удосужились указать что-либо в отношении упорядочения магазинов, поскольку не было никакого способа наблюдать за магазинами вне программного порядка. C(++)11 добавил целый набор правил для упорядочения хранилищ как часть новой спецификации многопоточности.
Реальная формулировка правила "как будто" найдена в §1.9/8 в стандарте:
- Доступ к изменчивым объектам оценивается строго по правилам абстрактной машины.
- При завершении программы все данные, записанные в файлы, должны быть идентичны одному из возможных результатов, которые могло бы дать выполнение программы в соответствии с абстрактной семантикой.
- Динамика ввода и вывода интерактивных устройств должна происходить таким образом, чтобы вывод запроса фактически доставлялся до того, как программа ожидает ввода. То, что составляет интерактивное устройство, определяется реализацией.
поскольку A
а также B
не изменчивы, это изменение порядка допускается.