¿Es un programa que nunca termina un programa válido de C ++?

15

¿Se requiere que un programa finalice? En otras palabras, ¿es un programa que se ejecuta para siempre técnicamente Comportamiento indefinido? Tenga en cuenta que esto no se trata de bucles vacíos. Hablar sobre programas que hacen "cosas" (es decir, comportamiento observable) para siempre.

Por ejemplo, algo como esto:

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 es más una cuestión académica, ya que empíricamente todos los compiladores sanos generarán el código esperado para el tipo de programa anterior (suponiendo, por supuesto, que no haya otra fuente de UB). Y sí, por supuesto, hay muchos programas que nunca terminan (os, embebidos, servidores). Sin embargo, el estándar es peculiar a veces, de ahí la pregunta.


Tangencial: muchas definiciones (¿algunas?) De "algoritmo" requieren que un algoritmo deba terminar , es decir, una serie de operaciones que nunca termina no se considera un algoritmo.


Tangencial. El problema de detención establece que no puede existir un algoritmo para determinar si un programa arbitrario termina para una entrada. Sin embargo, para este programa en particular, dado que no hay una rama que conduzca a salir de main, el compilador puede determinar fácilmente que el programa nunca terminará. Sin embargo, esto es irrelevante ya que la pregunta es abogado de idiomas.

bolov
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Samuel Liew

Respuestas:

15

No hay nada en el estándar C ++ que requiera que el programa, o cualquier subproceso dado, finalice. Lo más parecido a eso es [intro.progress] p1 , que dice

La implementación puede suponer que cualquier hilo eventualmente hará uno de los siguientes:

  • Terminar,
  • hacer una llamada a una función de E / S de la biblioteca,
  • realizar un acceso a través de un valor de gl volátil, o
  • realizar una operación de sincronización o una operación atómica.

[  Nota: Esto está destinado a permitir transformaciones del compilador, como la eliminación de bucles vacíos, incluso cuando no se pueda probar la terminación. -  nota final  ]

Mientras haya algún comportamiento observable, eventualmente, o mientras pase todo su tiempo bloqueado en una operación de E / S u otra llamada de biblioteca de bloqueo, esto no aplica, y el programa es válido (suponiendo que cumpla con todos los requisitos otros criterios de validez)

Daniel H
fuente
"una operación de E / S u otra llamada de biblioteca de bloqueo": el Estándar es bastante claro y solo enumera las operaciones de E / S. ¿Por qué agrega "u otra llamada de biblioteca de bloqueo"? También, que yo / O operación está ya incluido en su anterior " algún comportamiento observable".
MSalters
1
@MSalters std::mutex::lock()es una llamada a la biblioteca que es una operación de sincronización, incluida en la cuarta viñeta. Por lo tanto, no es cierto que solo se mencionen las llamadas de E / S.
Igor Tandetnik
Si está atascado en la entrada , pero nunca obtiene ninguno, es discutible si eso cuenta como observable.
Daniel H
4

Si. Desde[intro.progress]

La implementación puede suponer que cualquier hilo eventualmente hará uno de los siguientes:

  • Terminar,
  • hacer una llamada a una función de E / S de la biblioteca,
  • realizar un acceso a través de un valor de gl volátil, o
  • realizar una operación de sincronización o una operación atómica.

[ Nota: Esto está destinado a permitir transformaciones del compilador, como la eliminación de bucles vacíos, incluso cuando no se pueda probar la terminación. - nota final ]

Caleth
fuente
Creo que una pequeña descripción que indique que el programa hace E / S sería aconsejable.
KamilCuk
Entonces, siempre que las funciones get_inputy put_outputen el ejemplo de OP "hagan una llamada a una función de E / S de la biblioteca", ¿el programa debería ser válido incluso si no termina?
Algún tipo programador el
@Someprogrammerdude o accede a un valor volátil o atómico, Sí
Caleth el
curiosidad por el estándar pre c ++ 11, cuando no existía el modelo de memoria actual.
bolov
1
compiler does not know- Esto es irrelevante. El compilador puede saber y puede no saber, desde el punto de vista de la capa de lenguaje, la pregunta es si es válido, en cualquier caso.
KamilCuk