Це програма, яка ніколи не припиняє дійсну програму C ++?


15

Чи потрібно програму припинити? Іншими словами, це програма, яка працює вічно технічно Undefined Behavior? Зауважте, це не про порожні петлі. Якщо говорити про програми, які назавжди "наповнюють" (тобто спостерігається поведінка).

Наприклад, щось подібне:

int main()
{
    while (true)
    {
        try
        {
            get_input(); // calls IO
            process();
            put_output(); // calls IO, has observable behavior

            // never break, exit, terminate, etc
        } catch(...)
        {
            // ignore all exceptions
            // don't (re)throw
            // never go out of loop
        }
    }
}

Це скоріше академічне питання, оскільки емпірично всі розумні компілятори генерують очікуваний код для вищевказаного типу програми (якщо, звичайно, немає іншого джерела UB). І так, звичайно, існує дуже багато програм, які ніколи не припиняються (os, embeded, сервери). Однак іноді стандарт химерний, тому питання.


Тангенціальна: багато (деякі?) Визначення поняття «алгоритм» вимагають, щоб алгоритм повинен припинитися , тобто серія операцій, яка ніколи не припиняється, не вважається алгоритмом.


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


Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Самуель Liew

Відповіді:


15

У стандарті C ++ немає нічого, що вимагає завершення програми або будь-якого потоку. Найближче до цього - [intro.progress] p1 , який говорить

Реалізація може припускати, що з часом будь-який потік виконує одне з наступних дій:

  • припинити,
  • здійснити дзвінок у функцію вводу / виводу бібліотеки,
  • здійснити доступ через летючу glvalue, або
  • виконати операцію синхронізації або атомну операцію.

[  Примітка. Це покликано дозволити перетворення компілятора, такі як видалення порожніх циклів, навіть якщо припинення неможливо довести. -  кінцева примітка  ]

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


"операція вводу / виводу або інший блокуючий виклик бібліотеки" - Стандарт є досить зрозумілим і містить лише список операцій вводу / виводу. Чому ви додаєте "чи інший блокуючий дзвінок бібліотеки"? Крім того, що операція вводу / виводу вже включена у попередню " деяку спостережувану поведінку".
MSalters

1
@MSalters std::mutex::lock()- це бібліотечний виклик, який є операцією синхронізації, підпадаючи під четверту кулю. Тож це неправда, що згадуються лише дзвінки вводу-виводу.
Ігор Тандетник

Якщо вона застрягла на вході , але ніколи не отримує жодної, то можна вважати, чи вважається це спостережуваним.
Даніель Н

4

Так. З[intro.progress]

Реалізація може припускати, що з часом будь-який потік виконує одне з наступних дій:

  • припинити,
  • здійснити дзвінок у функцію вводу / виводу бібліотеки,
  • здійснити доступ через летючу glvalue, або
  • виконати операцію синхронізації або атомну операцію.

[ Примітка. Це покликано дозволити перетворення компілятора, такі як видалення порожніх циклів, навіть якщо припинення неможливо довести. - кінцева примітка ]


Я вважаю, що невеликий опис, який говорить про те, що програма робить введення / виведення, було б доцільним.
KamilCuk

Так що до тих пір, як get_inputі put_outputв прикладі ОП „робити дзвінок до функції вводу / виводу бібліотеки” програма повинна бути дійсною, навіть якщо вона не припиняється?
Якийсь програміст чувак

@Someprogrammerdude або отримати доступ до летючого або атомного значення, так
Caleth

цікаво щодо стандарту pre c ++ 11, коли не було поточної моделі пам'яті.
болов

1
compiler does not know- Це не має значення. Компілятор може знати, а може і не знати, з точки зору мовного рівня - питання полягає в тому, чи дійсний він, в будь-якому випадку.
KamilCuk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.