Что именно является правилом "как будто"?
Как видно из названия,
Типичный ответ:
Правило, которое разрешает любые и все преобразования кода, которые не изменяют наблюдаемое поведение программы
Время от времени мы продолжаем получать поведения от определенных реализаций, которые приписываются этому правилу. Много раз неправильно. Итак, что же это за правило. Стандарт не содержит четкого упоминания об этом правиле в качестве раздела или абзаца, так что конкретно подпадает под действие этого правила? Мне кажется, что это серая зона, которая подробно не определена стандартом. Может кто-нибудь уточнить детали со ссылкой на ссылки из стандарта.
Примечание: пометьте это как C и C++, потому что это относится к обоим языкам.
2 ответа
Что такое правило "как будто"?
Правило "как если" в основном определяет, какие преобразования разрешено выполнять реализации в легальной программе на C++. Короче говоря, все преобразования, которые не влияют на "наблюдаемое поведение" программы (точное определение см. Ниже), разрешены.
Цель состоит в том, чтобы предоставить реализациям свободу выполнения оптимизаций, пока поведение программы остается совместимым с семантикой, определенной Стандартом C++ в терминах абстрактной машины.
Где Стандарт вводит это правило?
Стандарт C++11 вводит правило "как будто" в параграфе 1.9/1:
Семантические описания в этом международном стандарте определяют параметризованную недетерминированную абстрактную машину. Настоящий международный стандарт не предъявляет требований к структуре соответствующих реализаций. В частности, им не нужно копировать или эмулировать структуру абстрактной машины. Скорее, соответствующие реализации требуются для эмуляции (только) наблюдаемого поведения абстрактной машины, как объяснено ниже.
Также пояснительная сноска добавляет:
Это положение иногда называют правилом "как будто", потому что реализация может свободно игнорировать любое требование этого международного стандарта, если в результате будет выполнено требование, насколько это можно определить из наблюдаемого поведения. программы. Например, фактическая реализация не должна оценивать часть выражения, если она может сделать вывод, что ее значение не используется и что не возникает никаких побочных эффектов, влияющих на наблюдаемое поведение программы.
Что именно предписывает правило?
Пункт 1.9/5 дополнительно определяет:
Соответствующая реализация, выполняющая правильно сформированную программу, должна производить то же наблюдаемое поведение, что и одно из возможных исполнений соответствующего экземпляра абстрактной машины с той же программой и тем же вводом. Однако, если любое такое выполнение содержит неопределенную операцию, этот международный стандарт не предъявляет никаких требований к реализации, выполняющей эту программу с этим вводом (даже в отношении операций, предшествующих первой неопределенной операции).
Стоит подчеркнуть, что это ограничение применяется только при "выполнении правильно сформированной программы", и что возможные результаты выполнения программы, которая содержит неопределенное поведение, не ограничены. Это также четко указано в пункте 1.9/4:
Некоторые другие операции описаны в этом международном стандарте как неопределенные (например, эффект попытки изменить объект const). [Примечание. Настоящий международный стандарт не предъявляет никаких требований к поведению программ, которые содержат неопределенное поведение. —Конечная записка]
Наконец, что касается определения "наблюдаемого поведения", пункт 1.9/8 гласит:
Минимальные требования к соответствующей реализации:
- Доступ к изменчивым объектам оценивается строго по правилам абстрактной машины.
- При завершении программы все данные, записанные в файлы, должны быть идентичны одному из возможных результатов, которые могло бы дать выполнение программы в соответствии с абстрактной семантикой.
- Динамика ввода и вывода интерактивных устройств должна происходить таким образом, чтобы вывод подсказки фактически доставлялся до того, как программа ожидает ввода. То, что составляет интерактивное устройство, определяется реализацией.
Все вместе они называются наблюдаемым поведением программы. [ Примечание: более строгие соответствия между абстрактной и фактической семантикой могут быть определены каждой реализацией. -конец примечания ]
Существуют ли ситуации, когда это правило не применяется?
Насколько мне известно, единственное исключение из правила "как если бы" - это разрешение на копирование / перемещение, которое допускается, даже если конструктор копирования, конструктор перемещения или деструктор класса имеют побочные эффекты. Точные условия для этого указаны в пункте 12.8/31:
При соблюдении определенных критериев реализация может опустить конструкцию копирования / перемещения объекта класса, даже если конструктор, выбранный для операции копирования / перемещения и / или деструктор для объекта, имеет побочные эффекты. [...]
В C11 правило никогда не называется этим именем. Однако C, как и C++, определяет поведение в терминах абстрактной машины. Правило "как будто" в C11 5.1.2.3p4 и p6:
В абстрактной машине все выражения оцениваются в соответствии с семантикой. Реальная реализация не должна оценивать часть выражения, если она может сделать вывод, что ее значение не используется и что не возникает никаких побочных эффектов (включая любые, вызванные вызовом функции или доступом к изменчивому объекту).
[...]
Минимальные требования к соответствующей реализации:
- Доступ к
volatile
объекты оцениваются строго по правилам абстрактной машины.- При завершении программы все данные, записанные в файлы, должны быть идентичны результату, который произойдет при выполнении программы в соответствии с абстрактной семантикой.
- Динамика ввода и вывода интерактивных устройств должна осуществляться в соответствии с 7.21.3. Цель этих требований заключается в том, чтобы небуферизованный или линейно-буферизованный вывод появлялся как можно быстрее, чтобы гарантировать, что сообщения-подсказки действительно появляются до того, как программа ожидает ввода.
Это наблюдаемое поведение программы.
В C, C++, Ada, Java, SML... на любом языке программирования, хорошо указанном путем описания (как правило, многих возможных, недетерминированных) поведения (й) программы (подвергаемых серии взаимодействий на портах ввода / вывода) Нет четкого правила "как будто".
Примером отдельного правила является то, которое говорит, что деление на ноль вызывает исключение (Ada, Caml) или нулевое разыменование вызывает исключение (Java). Вы можете изменить правило, чтобы указать что - то другое, и в итоге вы получите другой язык (который некоторые люди скорее назвали бы "диалектом"(*)). Существует отдельное правило, чтобы указать несколько разных применений языка программирования, таких как Грамматическое правило охватывает некоторые синтаксические конструкции.
(*) Диалект по мнению некоторых лингвистов - это язык с "армией". в этом контексте это может означать язык программирования без комитета и особой индустрии редакторов компиляторов.
Правило "как будто" не является отдельным правилом; оно не распространяется на какую-либо конкретную программу и даже не является правилом, которое можно обсуждать, удалять или изменять каким-либо образом: так называемое "правило" просто повторяет, что семантика программы определена, и может быть только переносимой (универсальной) определяется в терминах видимых взаимодействий исполнения программы с "внешним" миром.
Внешний мир может быть интерфейсами ввода / вывода (stdio), графическим интерфейсом пользователя, даже интерактивным интерпретатором, который выводит полученное значение чистого аппликативного языка. В C и C++ включены (неопределенно определенные) обращения к изменчивым объектам, что является еще одним способом сказать, что некоторые объекты в данной точке должны быть представлены в памяти строго в соответствии с ABI (двоичным интерфейсом приложения), не упоминая в явном виде ABI.
Определение того, что является следом выполнения, также называемое видимым или наблюдаемым поведением, определяет то, что подразумевается под "правилом как будто". Правило "как будто" пытается объяснить это, но, делая это, оно смущает людей больше, чем проясняет, поскольку дает выражение того, что является дополнительным семантическим правилом, дающим больше свободы реализации.
Резюме:
- Так называемое правило "как будто" не ослабляет никаких ограничений на реализацию.
- Вы не можете удалить правило "как будто" в любом языке программирования, указанном в терминах видимого поведения (следы выполнения, составленные для взаимодействия с внешним миром), чтобы получить отличный диалект.
- Вы не можете добавить правило "как если" к любому языку программирования, не указанному в терминах видимого поведения.