Является ли программа, которая никогда не завершает действительную программу C ++? - PullRequest
14 голосов
/ 05 ноября 2019

Требуется ли программа для завершения? Другими словами, это программа, которая работает навсегда технически неопределенным поведением? Обратите внимание, что это не о пустых циклах. Говоря о программах, которые «напичканы» (то есть наблюдаемым поведением) навсегда.

Например, что-то вроде этого:

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, серверы). Однако стандарт иногда бывает странным, поэтому возникает вопрос.


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


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

Ответы [ 2 ]

13 голосов
/ 05 ноября 2019

В стандарте C ++ нет ничего, что требовало бы завершения программы или любого другого потока. Наиболее близким к этому является [intro.progress] p1 , в котором говорится

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

  • завершить,
  • сделать вызов функции ввода-вывода библиотеки,
  • выполнить доступ через энергозависимое значение glvalue, или
  • выполнить операцию синхронизации илиатомарная операция.

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

Пока существует некоторое наблюдаемое поведение, в конце концов, или пока оно проводит все свое время, заблокированное на I /O операция или другой блокирующий вызов библиотеки, это не применимо, и программа действительна (при условии, что она соответствует всем другим критериям достоверности).

4 голосов
/ 05 ноября 2019

Да. С [intro.progress]

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

  • terminate,
  • сделать вызов функции ввода-вывода библиотеки,
  • выполнить доступ через энергозависимое значение glvalue, или
  • выполнить операцию синхронизации или атомарную операцию.

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

...