8 ms·
My 'favourite' bit of surprising (not undefined) behaviour I've seen recently in the C11 spec is around infinite loops, where void foo() { while (1) {} } will
by aidanhs 10y ago
My 'favourite' bit of surprising (not undefined) behaviour I've seen recently in the C11 spec is around infinite loops, where
void foo() { while (1) {} }
will loop forever, but
void foo(int i) { while (i) {} }
is permitted to terminate...even if i is 1:
> An iteration statement whose controlling expression is not a constant expression, that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate
To make things a bit worse, llvm can incorrectly both of the above terminate - https://bugs.llvm.org//show_bug.cgi?id=965 https://bugs.llvm.org//show_bug.cgi?id=965.
- deleted 10y ago[deleted]
- adamnemecek 10y agoWhat's the point of this?
- bcoates 10y agoIt allows the optimizer to assume away the halting problem; all nontrivial loops are obligated to halt.
- Gibbon1 10y agoI read this as, will confuse the snot out of hapless newbie programmers trying to learn C via stepping though their code in an IDE. While providing no practical benefit to programmers writing production code.
- blackflame7000 10y agoIt is necessary in order for the compiler to do transformation optimizations which do impact production code. Newbies shouldn't be writing production code without guidance anyways IMO.
- Thrillington 10y agoNewbies should probably turn off optimization entirely.
- blackflame7000 10y agoNo argument there, or at the very least whole program optimizations
- adamnemecek 10y agoWhat's the point of this though? Why are you letting programmers write non-functional code? When does the loop exactly terminate? I'm guessing the standard discusses this but at this point idk if I care about memorizing more C trivia.
- msbarnett 10y ago> What's the point of this though? Why are you letting programmers write non-functional code? He just told you. Because the only way to prevent it in general is to solve the halting problem. > When does the loop exactly terminate? In the general case this is provably impossible to determine. (all you're seeing here is that the compiler authors felt no need to add special case logic to handle "trivial" cases of the halting problem. If the compiler sees any expression in a loop test, it assumes the loop will halt some of the time)
- adamnemecek 10y ago> He just told you. Because the only way to prevent it in general is to solve the halting problem. I'm aware. I think that I might have misunderstood what the optimization really does.
- msbarnett 10y agoGrandparent presented this as a "surprising optimization" but I'd argue it's exactly what you'd expect when a compiler sees while(expression) -- he just happened to pick a trivial expression.
- deleted 10y ago[deleted]
- mnarayan01 10y agoThe idea (I assume) is to let compilers optimize away loops without determining that they terminate. I.e. the rule is more aimed at loops which would terminate, but this lets compilers avoid proving that they do in fact terminate.
- mnarayan01 10y agoIf the optimizer can determine that "nothing happens" in the loop, it can optimize the loop away without attempting to determine whether or not the loop terminates.
- pcvarmint 10y agoIt means that empty loops (loops with empty bodies) can be completely removed if the controlling expression has no side effects. > This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven. It means while(i) {} can be eliminated as if i were 0, because there are no side effects in the loop expression or the loop body, and what would be the point of the loop if it never terminated on a non-constant expression? As an optimization, the optimizer is allowed to eliminate it as a useless loop with no side effects. If you really want an infinite loop, you can use while (1) {}. There are cases where automatically generated C code might have empty loops which are useless. If you really want to go to sleep, use pause() or similar. An infinite loop eats up CPU cycles.
- rkv 10y ago> If you really want to go to sleep, use pause() or similar. An infinite loop eats up CPU cycles Yes but an infinite loop + sleep is okay, right?
- dfox 10y agoFrom compiler's POW call to sleep() is side-effect.
- TorKlingberg 10y agoIt's quite common in embedded systems to have the fault handler end with an infinite loop, to give the programmer a chance to attach a debugger an inspect the call stack. Sometimes this behavior is turned on or off with a debug flag, which can trigger this unexpected optimization if the flag is not a compile time constant.
- deleted 10y ago[deleted]
- fmap 10y agoThis definition is actually required for the correctness of many standard compiler optimizations such as partial redundancy elimination and code motion.