Процессор может переупорядочить два хранилища, если это не нарушает никаких гарантий, которые процессор может предоставить.Работа компилятора состоит в том, чтобы генерировать код для ЦП, который не позволяет выполнять оптимизацию, которая приводит к тому, что сгенерированный код нарушает стандарт Си.Другими словами, компилятор C принимает обещанный им код, который будет выполняться в соответствии с правилами стандарта C, и превращает его в код сборки, который на самом деле будет выполняться в соответствии с правилами стандарта C, полагаясь на процессор длязапускаться в соответствии с правилами спецификации его архитектуры.
Таким образом, если эти два хранилища оказываются в одной и той же ячейке памяти, невозможна «оптимизация», которая позволяет наблюдать неправильный результат в том же потоке.Это нарушило бы стандарт C, поэтому неработающий компилятор будет генерировать любой код, необходимый для того, чтобы не сломанный процессор не делал этого.Тем не менее, ничто не мешает оптимизации, которая может привести к тому, что другие потоки будут видеть странные промежуточные результаты, если только стандарт потоков вашей платформы не говорит что-то другое (и ни один из тех, о которых я знаю, не делает).
Если вам нужны межпоточные гарантии, вы должныиспользуйте атомарные операции, мьютексы или что-то еще, что ваша платформа предоставляет для этого.Если вы просто хотите, чтобы код работал, вам понадобятся специфические для платформы знания о том, на что действительно способна ваша платформа и какие существуют методы для их отключения на этой платформе (volatile
, флаги компилятора и т. Д.).