Що саме є правилом “як би”?


89

Як сказано в назві,

Що саме є правилом "як би"?

Типова відповідь, яку можна отримати:

Правило, яке допускає будь-які перетворення коду, які не змінюють спостережувану поведінку програми

Час від часу ми постійно отримуємо поведінку від певних реалізацій, які приписуються цьому правилу. Багато разів помилково. Отже, яке саме це правило. Стандарт не чітко згадує це правило як розділ чи абзац, тож що саме підпадає під сферу дії цього правила? Мені здається, що це сіра зона, яка не детально визначена стандартом. Чи може хтось детальніше описати деталі, посилаючись на посилання зі стандарту?

Примітка. Позначаючи це як C, так і C ++, оскільки це стосується обох мов.


2
Це стосується абстрактної машини.
Олексій Фрунзе

" Позначення цього як C, так і C ++, оскільки це стосується обох мов " Це актуально для будь-якої мови.
curiousguy

@AlexeyFrunze " Це стосується абстрактної машини " Це стосується стану "абстрактної машини", яка є інструментом, а не ціллю , і є неактуальною з точки зору відповідності, тому що це "абстрактно", тобто інструмент специфікації не є реальним.
curiousguy

Відповіді:


98

Що таке правило " як би "?

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

Мета полягає в тому, щоб надати реалізаціям свободу виконувати оптимізації, доки поведінка програми залишатиметься сумісною із семантикою, визначеною стандартом C ++, з точки зору абстрактної машини.


Де Стандарт вводить це правило?

Стандарт C ++ 11 вводить правило " як би " у пункті 1.9 / 1:

Семантичні описи в цьому міжнародному стандарті визначають параметризовану недетерміновану абстрактну машину. Цей міжнародний стандарт не встановлює вимог щодо структури відповідних реалізацій. Зокрема, їм не потрібно копіювати або наслідувати структуру абстрактної машини. Швидше, відповідні реалізації вимагають імітувати (лише) спостережувану поведінку абстрактної машини, як пояснено нижче.

Також пояснювальна виноска додає:

Це положення іноді називають правилом "ніби" , оскільки імплементація може нехтувати будь-якою вимогою цього Міжнародного стандарту, якщо результат є таким, ніби вимога була виконана, наскільки це можна визначити із спостережуваної поведінки програми. Наприклад, фактична реалізація не повинна оцінювати частину виразу, якщо вона може зробити висновок, що його значення не використовується, і що побічні ефекти, що впливають на спостережувану поведінку програми, не виробляються.


Що саме вимагає правило?

Пункт 1.9 / 5 додатково визначає:

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

Варто наголосити, що це обмеження застосовується лише при "виконанні добре сформованої програми" , і що можливі результати виконання програми, яка містить невизначену поведінку, є необмеженими. Це також чітко зазначено в пункті 1.9 / 4:

Деякі інші операції описані в цьому міжнародному стандарті як невизначені (наприклад, ефект спроби модифікувати об'єкт const). [Примітка: Цей міжнародний стандарт не встановлює вимог щодо поведінки програм, що містять невизначену поведінку . —Кінець примітки]

Нарешті, щодо визначення поняття " спостережувана поведінка ", пункт 1.9 / 8 звучить так:

Найменшими вимогами до відповідного впровадження є:

- Доступ до летких об'єктів оцінюється строго за правилами абстрактної машини.

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

- Динаміка введення та виведення інтерактивних пристроїв повинна відбуватися таким чином, щоб спонукальний вихід фактично доставлявся до того, як програма очікує на введення. Те, що становить інтерактивний пристрій, визначається реалізацією.

Вони в сукупності називаються спостережуваною поведінкою програми . [ Примітка : Більш суворе відповідність між абстрактною та фактичною семантикою може бути визначено кожною реалізацією. - кінцева примітка ]


Чи бувають ситуації, коли це правило не застосовується?

Наскільки мені відомо, єдиним винятком із правила " як би " є копіювання / переміщення, яке дозволено, навіть якщо конструктор копіювання, конструктор переміщення або деструктор класу мають побічні ефекти. Точні умови для цього вказані в параграфі 12.8 / 31:

Коли дотримуються певні критерії, реалізація може опускати конструкцію копіювання / переміщення об'єкта класу, навіть якщо конструктор, вибраний для операції копіювання / переміщення, та / або деструктор для об'єкта мають побічні ефекти . [...]


2
Я бачив це цитування. Незрозумілим є визначення спостережуваної поведінки. Що саме кваліфікується як спостережувана поведінка? Копіювання elision, яке є винятком із правила як би, є досить відомим і насправді не є частиною мого запитання.
Alok Save

2
@AlokSave: У стандарті C ми бачимо: "Доступ до летючого об'єкта, модифікація об'єкта, модифікація файлу або виклик функції, яка виконує будь-яку з цих операцій, є побічними ефектами". Імовірно, є щось еквівалентне у стандартах С ++. Неформально, я здогадуюсь "про все, що змінює його взаємодію із зовнішнім світом".
Олівер Чарлсворт

1
Будь-яка поведінка, яка змінює стан абстрактної машини (отже, щось, що змінює змінну, передану або глобальну змінну, або читає та записує на пристрої вводу-виводу).
Mats Petersson,

1
Чи означає це, що видаляти нескінченний цикл, який нічого не робить, дозволено, якщо після цього нічого не спостерігається?
harold 30.03.13

5
Окремо слід зазначити, що це стосується лише юридичних програм . Будь-що, що посилається на невизначену поведінку , явно не підпадає під охоплення.
vonbrand

15

У C11 правило ніколи не називається цим іменем. Однак С, як і С ++, визначає поведінку з точки зору абстрактної машини. Правило як би знаходиться в C11 5.1.2.3p4 та p6 :

  1. В абстрактній машині всі вирази обчислюються відповідно до семантики. Фактична реалізація не повинна оцінювати частину виразу, якщо вона може зробити висновок, що його значення не використовується, і що ніяких необхідних побічних ефектів не виробляється (включаючи будь-які, викликані викликом функції або доступом до нестабільного об'єкта).

  2. [...]

  3. Найменшими вимогами до відповідного впровадження є:

    • Доступ до volatileоб'єктів оцінюється строго за правилами абстрактної машини.
    • При припиненні програми всі дані, записані у файли, повинні бути ідентичними результату, який могло б дати виконання програми відповідно до абстрактної семантики.
    • Динаміка введення та виведення інтерактивних пристроїв повинна мати місце, як зазначено у 7.21.3 . Призначення цих вимог полягає в тому, щоб негативні або буферизовані вихідні дані з’явились якомога швидше, щоб гарантувати, що спонукальні повідомлення дійсно з’являються перед програмою, яка очікує на введення.

     

    Це спостерігається поведінка програми.


-1

У C, C ++, Ada, Java, SML ... будь-якою мовою програмування, добре визначеною, описуючи (як правило, багато можливих, недетермінованих) поведінку (ів) програми (підданої ряду взаємодій на портах вводу-виводу) , немає чіткого правила як би .

Прикладом чіткого правила є правило, яке говорить, що ділення на нуль викликає виняток (Ada, Caml) або нульове посилання - виняток (Java). Ви можете змінити правило, щоб вказати щось інше, і ви отримаєте іншу мову (що деякі люди воліють називати "діалектом" (*). Існує чітке правило, яке вказує на окреме використання мови програмування, наприклад граматичне правило охоплює деякі синтаксичні конструкції.

(*) Діалект, на думку деяких лінгвістів, - це мова з "армією". в цьому контексті це може означати мову програмування без комітету та конкретної галузі редакторів компіляторів.

Правило як би не є чітким правилом ; воно не охоплює жодної програми зокрема і навіть не є правилом, яке можна обговорювати, видаляти чи будь-яким чином змінювати : так зване "правило" просто повторює, що семантика програми визначена, і може бути лише портативною (універсальною) визначається в термінах видимих ​​взаємодій виконання програми із "зовнішнім" світом.

Зовнішнім світом можуть бути інтерфейси вводу-виводу (stdio), графічний інтерфейс, навіть інтерактивний інтерпретатор, що виводить результуюче значення чистої застосувальної мови. У C і C ++ включає (неясно вказаний) доступ до летких об'єктів, що є ще одним способом сказати, що деякі об'єкти в певній точці повинні бути представлені в пам'яті строго відповідно до ABI (Application Binary Interface), ніколи не згадуючи ABI явно.

Визначення того, що є слідом виконання , також зване видимою або спостережуваною поведінкою, визначає, що означає "правило як би". Правило начебто намагається це пояснити, але, роблячи це, воно більше бентежить людей, ніж роз'яснює речі, оскільки дає вираз додаткового семантичного правила, що дає більше свободи реалізації.

Короткий зміст:

  • Так зване "правило як би" не послаблює жодних обмежень щодо реалізацій.
  • Ви не можете видалити правило як би в жодній мові програмування, вказаному в терміні видимої поведінки (сліди виконання, складені для взаємодії із зовнішнім світом), щоб отримати чіткий діалект.
  • Ви не можете додати правило як би до будь-якої мови програмування, не вказаної в терміні видимої поведінки.

Якщо люди вважають, що я помиляюся, і існує чітке "як би правило", чому б їм не спробувати описати варіант C ++ (діалект) без цього "правила"? Що б взагалі означала специфікація C ++ без неї? Було б абсолютно неможливо сказати, чи відповідає компілятор. Або навіть визначити відповідність.
curiousguy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.