Während ich eine zweifelhafte Behauptung untersuchte , schrieb ich dieses kleine Testprogrammnoway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
Wenn ich das teste, bekomme ich:
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
Wat.
Wenn ich ohne Optimierungen kompiliere, hängt es wie erwartet. Ich habe mir die Baugruppe angesehen, und ohne Schnickschnack main
sieht die Funktion folgendermaßen aus:
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
Wo ud2
ist anscheinend eine Anweisung speziell für undefiniertes Verhalten. Die oben erwähnte zweifelhafte Behauptung "Eine Funktion, die niemals zurückkehrt, ist UB" wird verstärkt. Es fällt mir immer noch schwer zu glauben. Ja wirklich!? Sie können eine Spin-Schleife nicht sicher schreiben?
Meine Fragen sind also:
- Ist das eine korrekte Lesart dessen, was los ist?
- Wenn ja, kann mich jemand auf eine offizielle Ressource verweisen, die dies überprüft?
- In welcher Situation soll diese Art der Optimierung stattfinden?
Relevante Infos
$ clang --version
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
c
standards
undefined-behavior
luqui
quelle
quelle
int n = 0
===>unsigned int n = 0;
oder noch besser ..while (1);
unsigned int
Antworten:
Wenn Sie das ud2 für den Code erhalten, der jetzt in Frage kommt, ist der Compiler kein konformer C-Compiler. Sie könnten einen Compiler-Fehler melden.
Beachten Sie, dass dieser Code in C ++ tatsächlich UB ist. Beim Hinzufügen von Threads (C11 bzw. C ++ 11) wurde eine Vorwärtsfortschrittsgarantie für jeden Thread eingerichtet, einschließlich des Hauptausführungsthreads eines Programms, das nicht über mehrere Threads verfügt.
In C ++ müssen schließlich alle Threads ohne Ausnahmen fortschreiten. In C ist jedoch keine Schleife erforderlich, deren steuernder Ausdruck ein konstanter Ausdruck ist. Nach meinem Verständnis hat C diese Ausnahme hinzugefügt, da es in der eingebetteten Codierung bereits üblich war, a
while(1) {}
zum Aufhängen des Threads zu verwenden.Ähnliche Frage mit detaillierteren Antworten
quelle
ud2
aus dem C-Code, aber ich danke Ihnen, dass Sie die Informationen zur C ++ - Vorwärtsfortschrittsgarantie (ein Begriff, den ich anscheinend recherchieren kann) aufgenommen haben, nach dem ich wirklich gefragt habe, den ich aber optimiert habe Ich habe die Frage vorbereitet.