While investigating a dubious claim, I wrote this little test program noway.c
int proveit() { unsigned int n = 0; while (1) n++; return 0; } int main() { proveit(); return 0; } Testing this, I get:
$ clang -O noway.c $ ./a.out zsh: illegal hardware instruction ./a.out Wat.
If I compile without optimizations it hangs as expected. I looked at the assembly, and without all the bells and whistles the main function looks like this:
_main: ## @main pushq %rbp movq %rsp, %rbp ud2 Where ud2 is apparently is an instruction specifically for undefined behavior. The aforementioned dubious claim, "A function that never returns is UB", is reinforced. I still find it hard to believe though. Really!? You can't safely write a spin loop?
So I guess my questions are:
- Is this a correct reading of what is going on?
- If so, can someone point me to some official resource that verifies it?
- What is a situation in which you would want this type of optimization to occur?
Relevant info
$ 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/ 111 Answer
If you get the ud2 for the code that is now in the question, then the compiler is not a conforming C compiler . You could report a compiler bug.
Note that in C++ this code would actually be UB. When threads were added (C11 and C++11 respectively), there was put in place a forward progress guarantee for any thread, including the main execution thread of a program that's not multi-threaded.
In C++ all threads must eventually progress, with no exceptions. However in C, a loop whose controlling expression is a constant expression is not required to progress. My understanding is that C added this exception because it was already common practice in embedded coding to use a while(1) {} to hang the thread.
Similar question with more detailed answers
2