Ответ 1
Я думаю, что можно собрать это воедино, чтобы увидеть, что ответ подпадает под первый пункт в п. 5.1.2.3.6:
Доступ к изменчивым объектам оценивается строго по правилам абстрактной машины.
В дальнейшем, § 3.1 определяет "доступ" как:
читать или изменять значение объекта
и § 3.15 определяет "объект" как:
область хранения данных в среде исполнения, содержимое которой может представлять значения
Как ни странно, стандарт не содержит определения "летучего объекта". Он содержит определение "объекта, который имеет тип volatile -qualified" в § 6.7.3.6:
Объект, имеющий изменчивый тип -qualified, может быть изменен способами, неизвестными для реализации, или иметь другие неизвестные побочные эффекты. Поэтому любое выражение, относящееся к такому объекту, должно оцениваться строго в соответствии с правилами абстрактной машины, как описано в 5.1.2.3.
Кажется, не лишним было бы сделать вывод, что объект, имеющий изменчивый тип -qualified, имеет эту квалификацию именно для того, чтобы сообщить компилятору о том, что он на самом деле является изменчивым объектом, поэтому я не думаю, что он слишком растягивается, чтобы использовать эту формулировку в качестве на основе определения самого "изменчивого объекта" и определения изменчивого объекта как объекта, который может быть изменен способами, неизвестными для реализации, или иметь другие неизвестные побочные эффекты.
§ 5.1.2.3.2 определяет "побочный эффект" следующим образом:
Доступ к энергозависимому объекту, изменение объекта, изменение файла или вызов функции, которая выполняет любую из этих операций, являются побочными эффектами, которые являются изменениями в состоянии среды выполнения.
Поэтому я думаю, что мы можем собрать это вместе следующим образом:
-
Возвращение состояния выхода, которое должно быть возвращено в среду хоста, является явно изменением состояния среды выполнения, поскольку среда выполнения после получения, например,
EXIT_SUCCESS
, обязательно находится в другом состоянии, в котором она была бы получена, например,EXIT_FAILURE
. Поэтому возврат статуса выхода является побочным эффектом согласно § 5.1.2.3.2. -
exit()
- это функция, которая делает это, поэтому вызовexit()
сам по себе также является побочным эффектом согласно § 5.1.2.3.2. -
Стандарт, очевидно, не дает нам никаких подробностей о внутренней работе
exit()
или о том, какой механизмexit()
будет использовать для возврата этого значения в среду хоста, но бессмысленно предполагать, что доступ к объекту не будет задействован, поскольку объекты области хранения данных в среде исполнения, содержимое которых может представлять значения, а состояние выхода - значение. -
Поскольку мы не знаем, что, во всяком случае, будет делать среда хоста в ответ на это изменение состояния (не в последнюю очередь потому, что наша программа выйдет до того, как это произойдет), этот доступ имеет неизвестный побочный эффект, и поэтому доступ к объекту является изменчивый объект.
-
Поскольку вызов
exit()
обращается к энергозависимому объекту, это наблюдаемое поведение согласно § 5.1.2.3.6.
Это согласуется с нормальным пониманием объектов, которые имеют изменчивые типы -qualified, а именно то, что мы не можем оптимизировать удаленный доступ к таким объектам, если не можем определить, что никакие необходимые побочные эффекты не будут опущены, поскольку наблюдаемое поведение (в обычном повседневном смысле) может пострадать, если мы сделаем. Конечно, в этом случае нет видимого объекта типа volatile -qualified, поскольку к volatile объекту обращаются изнутри с помощью exit()
, и exit()
очевидно, даже не нужно писать в C. Но, несомненно, быть изменчивым объектом, и в п. 5.1.2.3 конкретно (трижды) содержится ссылка на летучие объекты, а не на объекты типа -qualified изменчивого (и не сноски к п. 6.2.4.2, это единственное место в стандарте упоминаются летучие объекты.)
Наконец, это, кажется, единственное прочтение, которое делает п. 5.1.2.3.6 понятным, поскольку интуитивно мы ожидаем, что "наблюдаемое поведение" программ на C, использующих только средства, описанные в стандарте, будет таким, что:
- Изменяет память таким образом, который виден вне самой программы;
- Изменяет содержимое файлов (которые по определению видны вне самой программы); а также
- Влияет на взаимодействие с интерактивными устройствами
что, по сути, является тем, к чему стремится п. 5.1.2.3.6.
редактировать
Кажется, что в комментариях есть небольшая полемика, по-видимому, связанная с идеями о том, что статус выхода может передаваться в регистрах и что регистры не могут быть объектами. Это возражение (без каламбура) тривиально опровергается:
-
Объекты могут быть объявлены с помощью спецификатора класса хранилища
register
, и такие объекты могут быть обозначены lvalues; -
Регистры с отображением в памяти, довольно вездесущие во встроенном программировании, дают такую же ясную демонстрацию, как и любые регистры, которые могут быть объектами, могут иметь адреса и могут быть обозначены lvalues. Действительно, регистры с отображением в памяти являются одним из наиболее распространенных видов использования
volatile
типов -qualified; -
mmap()
показывает, что даже содержимое файла может иногда иметь адреса и быть объектами.
В целом, ошибочно полагать, что объекты могут находиться только в или что "адреса" могут относиться только к местам в памяти ядра или банкам микросхем DRAM, или ко всему прочему, что можно условно назвать "памятью" или "БАРАН". Любой компонент среды выполнения, который способен хранить значение, включая регистры, может быть объектом, потенциально может иметь адрес и потенциально может быть обозначен lvalue, и именно поэтому определение "объекта" в стандарте в таких нарочито широких сроках.
Кроме того, такие разделы, как п. 5.3.2.1.9, идут на некоторую длину, чтобы провести различие между "значениями реальных объектов" и "[значениями], указанными в абстрактной семантике", что указывает на то, что фактические объекты являются реальными вещами, существующими в исполнении. окружение, отличное от абстрактной машины, - это вещи, с которыми действительно тесно связана спецификация, что ясно дает определение "объекта" в п. 3.15. Кажется неприемлемым сохранять позицию, в которой стандарт касается таких реальных объектов вплоть до и только до того момента, когда вызывается стандартная библиотечная функция, и в этот момент все такие проблемы испаряются, и такие вопросы внезапно становятся "вне С".