Что такое правило "как есть"?

Как гласит название,

Что такое правило "как есть" ?

Типичный ответ:

Правило, которое допускает любые и все преобразования кода, которые не изменяют наблюдаемое поведение программы

Время от времени мы продолжаем получать поведение от определенных реализаций, которые приписываются этому правилу. Много раз ошибочно. Итак, что именно это правило. В стандарте нет четкого упоминания этого правила как раздела или параграфа, так что же именно подпадает под сферу действия этого правила? Для меня это кажется серой областью, которая не определена подробно стандартом. Может кто-то уточнить детали, ссылающиеся на ссылки со стандарта.

Примечание. Отметьте это как C и С++, потому что это относится к обоим языкам.

Ответ 1

Что такое правило "как есть" ?

Правило "как есть" в основном определяет, какие преобразования, реализация которых разрешена для выполнения на законной программе на С++. Короче говоря, все преобразования, которые не влияют на "наблюдаемое поведение" программы (см. Ниже для точного определения), допускаются.

Цель состоит в том, чтобы предоставить реализациям свободу выполнения оптимизаций, пока поведение программы остается совместимым с семантикой, заданной стандартом С++, в терминах абстрактной машины.


Где стандартное вводит это правило?

Стандарт С++ 11 вводит правило "как есть" в пункте 1.9/1:

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

Кроме того, пояснительная сноска добавляет:

Это положение иногда называют "as-if" rule, потому что реализация вольна игнорировать любые требования этого Международный стандарт до тех пор, пока результат будет таким, как если бы требование выполнялось, насколько это можно определить из наблюдаемое поведение программы. Например, фактическая реализация не должна оценивать часть выражения, если она может вывести, что его значение не используется и что никаких побочных эффектов, влияющих на наблюдаемое поведение программы, не производится.


Что конкретно задает правило?

В пункте 1.9/5 далее указывается:

Соответствующая реализация , выполняющая хорошо сформированную программу, должна обеспечивать такое же наблюдаемое поведение как одно из возможных исполнений соответствующего экземпляра абстрактной машины с той же программой и тот же ввод. Однако, если какое-либо такое исполнение содержит операцию undefined, этот Международный Стандартные места не требуют выполнения этой программы с этим вводом (даже не в отношении операций, предшествующих первой операции undefined).

Следует подчеркнуть, что это ограничение применяется, когда "выполняется только правильно сформированная программа" и что возможные результаты выполнения программы, содержащей поведение undefined, не ограничены. Это также четко указано в пункте 1.9/4:

Некоторые другие операции описаны в этом Международном стандарте как undefined (например, эффект попытки изменить объект const). [Примечание: Настоящий международный стандарт не устанавливает никаких требований к поведение программ, содержащих поведение undefined. -end note]

Наконец, что касается определения "наблюдаемого поведения", то пункт 1.9/8 выглядит следующим образом:

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

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

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

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

Эти совокупности называются наблюдаемым поведением программы. [Примечание: более строгие Соответствие между абстрактной и фактической семантикой может быть определено каждой реализацией. -конец примечание]


Существуют ли ситуации, когда это правило не применяется?

Насколько я знаю, единственным исключением из правила as-if является copy/move elision, что допускается, хотя конструктор копирования, конструктор перемещения или деструктор класса имеют побочные эффекты. Точные условия для этого указаны в пункте 12.8/31:

При выполнении определенных критериев реализация допускает опустить конструкцию копирования/перемещения класса object, , даже если конструктор, выбранный для операции копирования/перемещения и/или деструктор для объекта имеют побочные эффекты. [...]

Ответ 2

В C11 правило никогда не вызывается этим именем. Однако C, как и С++, определяет поведение в терминах абстрактной машины. Правило as-if находится в C11 5.1.2.3p6:

  1. Наименьшие требования к соответствующей реализации:

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

     

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