Badając wątpliwe twierdzenie , napisałem ten mały program testowynoway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
Testując to, otrzymuję:
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
Wat.
Jeśli skompiluję bez optymalizacji, zawiesza się zgodnie z oczekiwaniami. Spojrzałem na zestaw i bez wszystkich dzwonków i gwizdów main
funkcja wygląda następująco:
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
Gdzie ud2
najwyraźniej jest instrukcja specjalnie dla nieokreślonego zachowania. Wspomniane wątpliwe twierdzenie: „Funkcja, która nigdy nie powraca to UB”, jest wzmocniona. Nadal trudno mi w to uwierzyć. Naprawdę!? Nie możesz bezpiecznie napisać pętli spinowej?
Myślę, że moje pytania to:
- Czy to poprawny odczyt tego, co się dzieje?
- Jeśli tak, to czy ktoś może skierować mnie do jakiegoś oficjalnego zasobu, który to zweryfikuje?
- W jakiej sytuacji chcesz tego rodzaju optymalizacja?
Istotne informacje
$ 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
źródło
źródło
int n = 0
===>unsigned int n = 0;
lub jeszcze lepiej ..while (1);
unsigned int
Odpowiedzi:
Jeśli otrzymasz ud2 dla kodu, który jest teraz w pytaniu, to kompilator nie jest zgodnym kompilatorem C. Możesz zgłosić błąd kompilatora.
Zauważ, że w C ++ tym kodem byłby UB. Po dodaniu wątków (odpowiednio C11 i C ++ 11) wprowadzono gwarancję postępu dla dowolnego wątku, w tym głównego wątku wykonawczego programu, który nie jest wielowątkowy.
W C ++ wszystkie wątki muszą się ostatecznie rozwijać, bez wyjątków. Jednak w C pętla, której kontrolne wyrażenie jest stałym wyrażeniem, nie jest wymagana do postępu. Rozumiem, że C dodał ten wyjątek, ponieważ było już powszechną praktyką w kodowaniu osadzonym, aby użyć a
while(1) {}
do zawieszenia wątku.Podobne pytanie z bardziej szczegółowymi odpowiedziami
źródło
ud2
kod C, ale dziękuję za podanie informacji o gwarancji postępu w C ++ (termin, który wydaje się, że będę w stanie zbadać), o co tak naprawdę pytałem, ale zostałem zoptymalizowany, ponieważ Przygotowywałem pytanie.