C 2018 6.7.3 8 гласит:
Объект, имеющий тип с изменчивой квалификацией, может быть изменен способами, неизвестными для реализации, или иметь другие неизвестные побочные эффекты.Поэтому любое выражение, относящееся к такому объекту, должно оцениваться строго в соответствии с правилами абстрактной машины, как описано в 5.1.2.3.…
Поскольку *(volatile int*)0x1234;
является выражением, относящимся к объекту сТип volatile-квалифицирован, оценивая его, должен получить доступ к объекту(Это предполагает, что 0x1234
обозначает действительную ссылку на некоторый объект в реализации C, конечно.)
Per C 2018 5.1.2.3 4:
В аннотациимашина, все выражения оцениваются в соответствии с семантикой.Реальная реализация не должна оценивать часть выражения, если она может сделать вывод, что его значение не используется и что не возникает никаких побочных эффектов (включая любые, вызванные вызовом функции или доступом к энергозависимому объекту).
Согласно C 2018 6.5 1:
Выражение - это последовательность операторов и операндов, которая задает вычисление значения, обозначает объект или функцию, генерирует побочные эффекты или чтовыполняет их комбинацию.
Таким образом, выражение определяет вычисление значения.Пункт 5.1.2.3 4 говорит нам, что эта оценка выполняется абстрактной машиной, а 6.7.3 8 говорит нам, что фактическая реализация выполняет эту оценку, которую выполняет машина абстракции.
Одно предостережение состоит в том, что составляет «доступ».»Определяется реализацией.«Доступ», как определено стандартом C, включает в себя как чтение, так и запись (C 3.1 1), но стандарт C не может указать, что он означает чтение или запись на некоторый конкретный аппаратный компонент.
На ходудалее на language-lawyer, территория, C 6.3.2.1 2 говорит нам:
За исключением случаев, когда это операнд оператора sizeof
, унарный оператор &
, оператор ++
оператор --
или левый операнд оператора .
или оператор присваивания, lvalue, у которого нет типа массива, преобразуется в значение, хранящееся в назначенном объекте (и больше не является lvalue);это называется преобразованием lvalue.
Таким образом, поскольку *(volatile int*)0x1234;
является lvalue, посредством оператора *
и не является операндом перечисленных операторов, оно преобразуется в значениехранится в объекте.Таким образом, это выражение указывает вычисление значения, которое хранится в объекте.