Рассмотрим следующий фрагмент кода:
volatile int a;
volatile int b;
int x;
void func() {
a = 1;
x = 0; /* dummy statement */
b = 2;
}
В этом фрагменте кода назначение x представляет собой точку последовательности.Следовательно, согласно стандарту C90, доступ к энергозависимой переменной a должен быть завершен до того, как начнется доступ к b.При переводе этого фрагмента кода на ассемблер x86-64 тело функции переводится следующим образом:
movl $1, a(%rip)
movl $0, x(%rip)
movl $2, b(%rip)
Теперь при выполнении этого кода ЦП может изменить порядок доступа к памяти, тем самым нарушая требованиестандарта C, что доступ к a и b выполняется по порядку.Итак, не является ли этот перевод неправильным, и не нужно ли компилятору вставлять барьеры памяти для обеспечения порядка?
Редактировать: Рассмотрим случай, когда a и b являются переменными, общими для двух потоков.В этом случае протокол синхронизации между двумя потоками может опираться на тот факт, что доступ к a и b происходит по порядку.Таким образом, когда ЦП переупорядочивает доступ, это может нарушить этот протокол (на самом деле я не пытаюсь реализовать такой протокол, мне просто интересно, какова правильная интерпретация стандарта C).