Рассмотрим следующую последовательность записей в память volatile
, которую я взял из статьи Дэвида Чисналла в InformIT, "Понимание C11 и С++ 11 Atomics":
volatile int a = 1;
volatile int b = 2;
a = 3;
Мое понимание из С++ 98 состояло в том, что эти операции не могли быть переупорядочены, на С++ 98 1.9:
конформным реализации требуется, чтобы эмулировать (только) наблюдаемое поведение абстрактной машины как объяснено ниже... Наблюдаемое поведение абстрактной машины - это ее последовательность чтения и записи в изменчивые данные и вызовы функций библиотечного ввода/вывода
Chisnall говорит, что ограничение на сохранение порядка относится только к отдельным переменным, записывая, что соответствующая реализация может генерировать код, который делает это:
a = 1;
a = 3;
b = 2;
Или это:
b = 2;
a = 1;
a = 3;
С++ 11 повторяет формулировку С++ 98, в которой
конформным реализации требуется, чтобы эмулировать (только) наблюдаемое поведение абстрактной машины, как объяснено ниже.
но говорит об этом volatile
(1.9/8):
Доступ к неустойчивым объектам оценивается строго в соответствии с правилами абстрактной машины.
1.9/12 говорит, что доступ к значению volatile
glvalue (который включает в себя переменные a
, b
и c
выше) является побочным эффектом, а 1.9/14 говорит, что побочные эффекты в одном полном выражение (например, оператор) должно предшествовать побочным эффектам более позднего полного выражения в том же потоке. Это приводит меня к выводу, что два переупорядочения Chisnall недействительны, поскольку они не соответствуют порядку, продиктованному абстрактной машиной.
Я что-то пропускаю или ошибаюсь в Chisnall?
(Обратите внимание, что это не вопрос о потоке. Вопрос заключается в том, разрешено ли компилятору переупорядочивать обращения к различным переменным volatile
в одном потоке.)