Ответ 1
Компилятор не может изменить порядок работы memcpy()
до hardware_reg = 1
или после hardware_reg = 0
- то, что обеспечит volatile
- по крайней мере, насколько поток команд генерирует компилятор. Вызов функции не обязательно является "барьером памяти", но это точка последовательности.
В стандарте C99 говорится о volatile
(5.1.2.3/5 "Выполнение программы" ):
В точках последовательности летучие объекты стабильны в том смысле, что предыдущие обращения полный и последующий доступ еще не произошли.
Итак, в точке последовательности, представленной memcpy()
, должен произойти неустойчивый доступ к записи 1
, и невозможен доступ к записи 0
.
Однако есть две вещи, которые я хотел бы отметить:
-
В зависимости от того, что
<something>
, если ничего не сделано с целевым буфером, компилятор может полностью удалить операциюmemcpy()
. Именно по этой причине Microsoft придумала функциюSecureZeroMemory()
.SecureZeroMemory()
работает сvolatile
квалифицированными указателями, чтобы предотвратить отключение записи. -
volatile
не обязательно подразумевает барьер памяти (который является аппаратной вещью, а не только кодовым заказом), поэтому, если вы работаете на машине с несколькими процессорами или определенными типами оборудования, вы может потребоваться явно вызвать барьер памяти (возможно,wmb()
в Linux).Начиная с MSVC 8 (VS 2005), документы Microsoft, что ключевое слово
volatile
подразумевает соответствующий барьер памяти, поэтому может потребоваться отдельный специальный вызов барьера памяти:Кроме того, при оптимизации компилятор должны поддерживать порядок среди ссылки на изменчивые объекты как ссылки на другие глобальные объекты. В частности,
-
Запись в изменчивый объект (volatile write) имеет Release семантика; ссылка на глобальную или статический объект, который возникает до пишите в изменчивый объект в последовательность команд будет выполняться до эта волатильная запись в скомпилированном двоичный файл.
-
Чтение изменчивого объекта (volatile read) имеет семантику Acquire; ссылка на глобальную или статическую объект, который возникает после чтения энергозависимая память в инструкции после этого произойдет последовательность волатильное чтение в скомпилированном двоичном файле.
-