Un programma che non termina mai un programma C ++ valido?


15

È necessario terminare un programma? In altre parole, è un programma che funziona per sempre tecnicamente un comportamento indefinito? Nota che non si tratta di loop vuoti. Parlando di programmi che fanno "cose" (cioè comportamenti osservabili) per sempre.

Ad esempio qualcosa del genere:

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

Questa è più una domanda accademica, dal momento che empiricamente tutti i compilatori sani genereranno il codice previsto per il tipo di programma di cui sopra (supponendo ovviamente che non vi siano altre fonti di UB). E sì, ovviamente ci sono molti programmi che non si chiudono mai (os, embed, server). Tuttavia lo standard è a volte bizzarro, quindi la domanda.


Tangenziale: molte (alcune?) Definizioni di "algoritmo" richiedono che un algoritmo debba terminare , ovvero una serie di operazioni che non si interrompe mai non è considerata un algoritmo.


Tangenziale. Il problema di arresto afferma che non può esistere un algoritmo per determinare se un programma arbitrario termina per un input. Tuttavia, per questo particolare programma poiché non esiste alcun ramo che porta a uscire da main, il compilatore può facilmente determinare che il programma non finirà mai. Ciò è tuttavia irrilevante in quanto la domanda è un avvocato di lingua.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Samuel Liew

Risposte:


15

Non esiste nulla nello standard C ++ che richieda la chiusura del programma o di un determinato thread. La cosa più vicina a ciò è [intro.progress] p1 , che dice

L'implementazione può presumere che qualsiasi thread alla fine eseguirà una delle seguenti operazioni:

  • terminare,
  • effettuare una chiamata a una funzione I / O della libreria,
  • eseguire un accesso attraverso un valore volatile, oppure
  • eseguire un'operazione di sincronizzazione o un'operazione atomica.

[  Nota: questo ha lo scopo di consentire trasformazioni del compilatore come la rimozione di loop vuoti, anche quando non è possibile provare la terminazione. -  nota finale  ]

Finché c'è qualche comportamento osservabile, eventualmente, o fino a quando trascorre tutto il suo tempo bloccato su un'operazione di I / O o un'altra chiamata di libreria di blocco, questo non si applica e il programma è valido (supponendo che soddisfi tutti i altri criteri di validità).


"un'operazione di I / O o un'altra chiamata di libreria di blocco": lo standard è abbastanza chiaro e elenca solo le operazioni di I / O. Perché stai aggiungendo "o un'altra chiamata di libreria bloccante"? Inoltre, che io / O operazione è già incluso nel tuo precedente " un po 'di comportamento osservabile".
MSalters,

1
@MSalters std::mutex::lock()è una chiamata in libreria che è un'operazione di sincronizzazione, che rientra nel quarto punto elenco. Quindi non è vero che sono menzionate solo le chiamate I / O.
Igor Tandetnik,

Se è bloccato sull'input , ma non ne ottiene mai, è discutibile se ciò sia considerato osservabile.
Daniel H,

4

Sì. A partire dal[intro.progress]

L'implementazione può presumere che qualsiasi thread alla fine eseguirà una delle seguenti operazioni:

  • terminare,
  • effettuare una chiamata a una funzione I / O della libreria,
  • eseguire un accesso attraverso un valore volatile, oppure
  • eseguire un'operazione di sincronizzazione o un'operazione atomica.

[ Nota: questo ha lo scopo di consentire trasformazioni del compilatore come la rimozione di loop vuoti, anche quando non è possibile provare la terminazione. - nota finale ]


Credo che sarebbe consigliabile una breve descrizione in cui si afferma che il programma esegue l'I / O.
KamilCuk,

Quindi, fintanto che le funzioni get_inpute put_outputnell'esempio degli OP "effettuano una chiamata a una funzione I / O della libreria" il programma dovrebbe essere valido anche se non termina?
Qualche programmatore, amico, il

@Someprogrammerdude o accedi a un valore volatile o atomico, Sì
Caleth

curioso dello standard pre c ++ 11, quando non esisteva il modello di memoria attuale.
Bolov,

1
compiler does not know- Questo è irrilevante. Il compilatore può sapere e potrebbe non sapere, dal punto di vista del livello linguistico: la domanda è se è valida, in ogni caso.
KamilCuk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.