Um programa que nunca termina um programa C++ válido?




language-lawyer undefined-behavior (2)

Não há nada no padrão C ++ que exija que o programa ou qualquer thread fornecido seja finalizado. O mais próximo disso é [intro.progress]p1 , que diz

A implementação pode assumir que qualquer thread acabará por executar um dos seguintes procedimentos:

  • terminar,
  • faça uma chamada para uma função de E / S da biblioteca,
  • realizar um acesso através de um valor de volume volátil ou
  • executar uma operação de sincronização ou uma operação atômica.

[ Nota: Isso visa permitir transformações do compilador, como remoção de loops vazios, mesmo quando a finalização não puder ser comprovada. - nota final ]

Contanto que exista algum comportamento observável, eventualmente, ou contanto que gaste todo o seu tempo bloqueado em uma operação de E / S ou outra chamada de biblioteca de bloqueio, isso não se aplica e o programa é válido (supondo que ele atenda a todas as outros critérios de validade).

É necessário um programa para terminar? Em outras palavras, é um programa que executa para sempre o comportamento indefinido tecnicamente? Observe que não se trata de loops vazios. Falando sobre programas que fazem "coisas" (ou seja, comportamento observável) para sempre.

Por exemplo, algo como isto:

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
        }
    }
}

Esta é mais uma questão acadêmica, pois empiricamente todos os compiladores sãos gerarão o código esperado para o tipo de programa acima (assumindo, é claro, nenhuma outra fonte de UB). E sim, é claro que existem muitos programas que nunca terminam (SO, incorporado, servidores). No entanto, o padrão é peculiar às vezes, daí a questão.

Tangencial: muitas (algumas?) Definições de "algoritmo" exigem que um algoritmo seja finalizado , ou seja, uma série de operações que nunca termina não é considerada um algoritmo.

Tangencial. O problema de parada afirma que não existe um algoritmo para determinar se um programa arbitrário termina para uma entrada. No entanto, para este programa em particular, uma vez que não há ramificação que saia do main, o compilador pode determinar facilmente que o programa nunca terminará. No entanto, isso é irrelevante, pois a questão é o advogado da linguagem.


Sim. De [intro.progress]

A implementação pode assumir que qualquer thread acabará por executar um dos seguintes procedimentos:

  • terminar,
  • faça uma chamada para uma função de E / S da biblioteca,
  • realizar um acesso através de um valor de volume volátil ou
  • executar uma operação de sincronização ou uma operação atômica.

[ Nota: Isso visa permitir transformações do compilador, como remoção de loops vazios, mesmo quando a finalização não puder ser comprovada. - nota final ]







undefined-behavior