Ist ein Programm, das niemals ein gültiges C++-Programm beendet?




language-lawyer undefined-behavior (2)

Muss ein Programm beendet werden? Mit anderen Worten, ist ein Programm, das für immer technisch Undefiniertes Verhalten ausführt? Beachten Sie, dass es sich nicht um leere Schleifen handelt. Sprechen über Programme, die für immer "Zeug" (dh beobachtbares Verhalten) tun.

ZB so etwas:

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

Dies ist eher eine akademische Frage, da empirisch alle vernünftigen Compiler erwarteten Code für die obige Art von Programm generieren werden (vorausgesetzt natürlich keine andere Quelle von UB). Und ja, natürlich gibt es viele Programme, die niemals enden (os, eingebettet, Server). Allerdings ist der Standard manchmal skurril, daher die Frage.

Tangential: Viele (einige?) Definitionen von "Algorithmus" erfordern, dass ein Algorithmus beendet wird , dh eine Reihe von Operationen, die niemals beendet werden, wird nicht als Algorithmus betrachtet.

Tangential. Das Problem des Anhaltens besagt, dass kein Algorithmus vorhanden sein kann, um zu bestimmen, ob ein beliebiges Programm für eine Eingabe beendet wird. Da es jedoch für dieses spezielle Programm keinen Zweig gibt, der zum Verlassen des Hauptmenüs führt, kann der Compiler leicht bestimmen, dass das Programm niemals enden wird. Dies ist jedoch irrelevant, da es sich um einen Sprachjuristen handelt.


Es gibt nichts im C ++ - Standard, bei dem das Programm oder ein bestimmter Thread beendet werden muss. Das nächste, was dem am nächsten kommt, ist [intro.progress]p1 , das besagt

Die Implementierung kann davon ausgehen, dass ein Thread irgendwann eine der folgenden Aktionen ausführt:

  • kündigen,
  • Rufen Sie eine Bibliotheks-E / A-Funktion auf.
  • einen Zugriff über einen flüchtigen Wert durchführen, oder
  • Führen Sie eine Synchronisationsoperation oder eine atomare Operation durch.

[ Hinweis: Dies soll Compiler-Transformationen wie das Entfernen leerer Schleifen ermöglichen, auch wenn die Beendigung nicht bewiesen werden kann. - Endnote ]

Solange irgendwann ein beobachtbares Verhalten vorliegt oder die gesamte Zeit für eine E / A-Operation oder einen anderen Blockierungsbibliotheksaufruf blockiert ist, gilt dies nicht und das Programm ist gültig (vorausgesetzt, es erfüllt alle Anforderungen) andere Gültigkeitskriterien).


Ja. Aus [intro.progress]

Die Implementierung kann davon ausgehen, dass ein Thread irgendwann eine der folgenden Aktionen ausführt:

  • kündigen,
  • Rufen Sie eine Bibliotheks-E / A-Funktion auf.
  • einen Zugriff über einen flüchtigen Wert durchführen, oder
  • Führen Sie eine Synchronisationsoperation oder eine atomare Operation durch.

[ Hinweis: Dies soll Compiler-Transformationen wie das Entfernen leerer Schleifen ermöglichen, auch wenn die Beendigung nicht bewiesen werden kann. - Endnote ]





undefined-behavior