Является ли статус выхода наблюдаемым поведением? - PullRequest
0 голосов
/ 17 декабря 2018

C 2018 5.1.2.3 6 говорит:

Минимальные требования к соответствующей реализации:

  • Доступ к летучим объектам оценивается строго в соответствии справила абстрактной машины.

  • При завершении программы все данные, записанные в файлы, должны быть идентичны результату, который произойдет при выполнении программы в соответствии с абстрактной семантикой.

  • Динамика ввода и вывода интерактивных устройств должна осуществляться в соответствии с 7.21.3.Цель этих требований заключается в том, чтобы небуферизованные или строковые буферизованные выходные данные появлялись как можно скорее, чтобы гарантировать, что сообщения-подсказки действительно появляются до того, как программа ожидает ввода.

Это наблюдаемыйПоведение программы.

На первый взгляд, это не включает статус завершения программы.

Относительно exit(status), 7.22.4.4 5 говорит:

Наконец, управление возвращается в среду хоста.Если значение status равно нулю или EXIT_SUCCESS, возвращается определяемая реализацией форма статуса успешное завершение .Если значение status равно EXIT_FAILURE, возвращается определяемая реализацией форма статуса неудачное завершение .В противном случае возвращаемый статус определяется реализацией.

Стандарт не говорит нам, что это является частью наблюдаемого поведения.Конечно, не имеет смысла, чтобы это exit поведение было описанием чисто абстрактной машины С;возвращение значения в окружающую среду не имеет смысла, если оно не наблюдается в окружающей среде.Поэтому мой вопрос не столько в том, является ли наблюдаемый статус выхода, сколько в том, является ли это дефектом в определении наблюдаемого поведения стандарта Си.Или в стандарте есть где-то еще текст, который применяется?

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Я думаю, что можно собрать это воедино, чтобы увидеть, что ответ подпадает под первый пункт маркированного списка в п. 5.1.2.3.6:

Доступ к летучим объектам оценивается строго в соответствии с правиламиабстрактная машина

Глядя дальше, § 3.1 определяет «доступ» как:

для чтения или изменения значения объекта

и § 3.15 определяет «объект» как:

область хранения данных в среде исполнения, содержимое которой может представлять значения

Стандарт, как ни странно, содержитнет определения «летучего объекта».Он содержит определение «объекта с типом, определенным с помощью volatile» в § 6.7.3.6:

Объект с типом с квалифицированным значением может быть изменен способами, неизвестными реализации или имеющимидругие неизвестные побочные эффекты.Поэтому любое выражение, относящееся к такому объекту, должно оцениваться строго в соответствии с правилами абстрактной машины, как описано в п. 5.1.2.3.

Кажется, что нет смысла выводить, что объект, имеющий изменчивуюквалифицированный тип имеет эту квалификацию именно для того, чтобы сообщить компилятору о том, что он на самом деле является энергозависимым объектом, поэтому я не думаю, что он слишком сильно растягивается, чтобы использовать эту формулировку в качестве основы для определения самого «летучего объекта», иопределить изменчивый объект как объект, который может быть изменен способами, неизвестными реализации или иметь другие неизвестные побочные эффекты.

§ 5.1.2.3.2 определяет «побочный эффект» следующим образом:

Доступ к энергозависимому объекту, изменение объекта, изменение файла или вызов функции, выполняющей любую из этих операций, являются побочными эффектами, которые являются изменениями в состоянии среды выполнения.

Так что я думаю, что мы можем собрать это вместе следующим образом:

  1. Возвращение состояния выхода, которое должно быть возвращено в среду хоста, очевидно, является изменением состояния среды выполнения, поскольку среда выполнения после получения, например, EXIT_SUCCESS, обязательно находится в другом состоянии, чем это было быесли бы он получил, например, EXIT_FAILURE.Поэтому возврат состояния выхода является побочным эффектом согласно § 5.1.2.3.2

  2. exit() - это функция, которая делает это, поэтому вызов exit() сам по себе также является побочным эффектомсогласно § 5.1.2.3.2.

  3. Стандарт, очевидно, не дает нам никаких подробностей о внутренней работе exit() или о том, какой механизм exit() будет использовать для возврата этого значения в среду хоста, но бессмысленно полагать,что доступ к объекту не будет задействован, поскольку объекты являются областями хранения данных в среде выполнения, содержимое которых может представлять значения, а состояние выхода является значением.

  4. Поскольку мы неНе знаю, что, если вообще что-нибудь, будет делать среда хоста в ответ на это изменение состояния (не в последнюю очередь потому, что наша программа вышла до того, как это произойдет), этот доступ имеет неизвестный побочный эффект, и поэтому доступ к объекту является изменчивым объектом.,

  5. Поскольку вызов exit() обращается к энергозависимому объекту, это наблюдаемое поведение согласно § 5.1.2.3.6.

Это согласуется снормальный тыпонимание объектов, которые имеют изменчиво-квалифицированные типы, а именно то, что мы не можем оптимизировать удаленный доступ к таким объектам, если мы не можем определить, что никакие необходимые побочные эффекты не будут опущены, потому что наблюдаемое поведение (в обычном повседневном смысле) может быть затронуто, если мыделать.Конечно, в этом случае нет видимого объекта типа volatile-квалифицированного, потому что к volatile объекту вопрос доступен изнутри exit(), и, очевидно, exit() даже не нужно писать на C. Но, несомненно,энергозависимый объект, а в п. 5.1.2.3 конкретно (трижды) содержится ссылка на энергозависимые объекты, а не на объекты квалифицируемого типа (кроме сноски к п. 6.2.4.2), это единственное место в стандартных энергозависимых объектахупоминаются.)

Наконец, это, кажется, единственное чтение, которое делает п. 5.1.2.3.6 понятным, поскольку интуитивно мы ожидаем «наблюдаемое поведение» программ на C, использующих только средства, описанныестандартным является то, что свободно:

  • Изменяет память таким образом, который виден за пределами самой программы;
  • Изменяет содержимое файлов (которые по определению видны за пределамисама программа);и
  • Влияет на взаимодействие с интерактивными устройствами

, что, по-видимому, в сущности то, к чему стремится п. 5.1.2.3.6.

Редактировать

Кажется, что в комментариях есть небольшая полемика, по-видимому, связанная с идеями о том, что статус выхода может передаваться в регистрах, и что регистры не могут быть объектами.Это возражение (без каламбура) тривиально отклоняется:

  1. Объекты могут быть объявлены с помощью спецификатора класса хранения register, и такие объекты могут быть обозначены lvalues;

  2. Регистры с отображением в памяти, довольно вездесущие во встроенном программировании, обеспечивают такую ​​же ясную демонстрацию, как и любые регистры, которые могут быть объектами, могут иметь адреса и могут быть обозначены lvalues.Действительно, регистры с отображением в памяти являются одним из наиболее распространенных типов volatile -качественных типов;

  3. mmap() показывает, что даже содержимое файла может иногда иметь адреса и быть объектами.

В общем, ошибочно полагать, что объекты могут находиться только внутри или что «адреса» могут относиться только к расположениям в памяти ядра или к банкам чипов DRAM или к чему-либо еще.что можно условно назвать «памятью» или «оперативной памятью». Любой компонент среды выполнения, который способен хранить значение, включая регистры, может быть объектом, может иметь адрес и потенциально может быть обозначен lvalue, и именно поэтому определение "Объект "в стандарте приведен в таких намеренно широких терминах.

Кроме того, такие разделы, как § 5.3.2.1.9, идут на некоторые длины, чтобы провести различие между" значениями фактических объектов "и" [значениями] определяется абстрактной семантикой ", что указывает на то, что фактические объекты являются реальными вещами, существующими в среде выполнения, отличной от абстрактной машины, и являются вещами, с которыми действительно тесно связана спецификация, поскольку определение" объекта "в п. 3.15 делаетЧисто.Кажется несостоятельным поддерживать позицию, в которой стандарт касается таких реальных объектов, вплоть до и только до того момента, когда вызывается стандартная библиотечная функция, и в этот момент все такие проблемы испаряются, и такие вопросы внезапно становятся «вне С».

0 голосов
/ 09 января 2019

Я прочитал документацию по функции system (7.22.4.8 Системная функция).Он содержит:

Возвращает

Если аргумент является нулевым указателем, системная функция возвращает ненулевое значение, только если доступен командный процессор.Если аргумент не является нулевым указателем, и системная функция возвращает, он возвращает значение, определенное реализацией.

Это похоже на стандартное условие для системы, где программа на С (или болеекак правило, пользовательская команда) не может запустить другую команду и / или где команда не будет ничего возвращать вызывающей стороне.В этом последнем случае выходное значение не будет наблюдаемым (в обычном смысле).

В этой интерпретации наблюдаемость выходного значения будет просто определяться реализацией.И это согласуется с тем, что в явном поведении программы это явно не цитируется.

Я могу вспомнить старую систему ( Solar 16 ) из 70-х, где команды запускались сcall для стандартных команд или run для пользовательских команд, и когда параметры могут быть переданы только для подкоманд после определенного запроса от программы.Компилятора С там не было, но если бы кому-то удалось его реализовать, возвращаемое значение не было бы заметным.

0 голосов
/ 06 января 2019

Предполагается, что состояние выхода должно быть доступно для среды хоста, в которой выполняется реализация.То, что хост-среда делает с этим, выходит за рамки стандарта.

...