14

Is an infinite loop like for (;;); undefined behavior in C? (It is for C++, but I don't know about C.)

Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886

2 Answers2

13

No, the behavior of a for (;;) statement is well defined in C.

N1570, which is essentially identical to the offical 2011 ISO C standard, says, in section 6.8.5 paragraph 6:

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.

with two footnotes:

An omitted controlling expression is replaced by a nonzero constant, which is a constant expression.

This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven.

The first footnote makes it clear that for (;;) is treated as if it had a constant controlling expression.

The point of the rule is to permit optimizations when the compiler can't prove that the loop terminates. But if the controlling expression is constant, the compiler can trivially prove that the loop does or does not terminate, so the additional permission isn't needed.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • *"The point of the rule is to permit optimizations when the compiler can't prove that the loop terminates. But if the controlling expression is constant, the compiler can trivially prove that the loop does or does not terminate."* I'd like to agree, but then why would `while(1);` be undefined in C++? Wouldn't the same reasoning apply? – user541686 Mar 24 '13 at 06:09
  • @Mehrdad: IMHO it should, but the C++ standard doesn't exclude constant controlling expressions from its version of the rule. – Keith Thompson Mar 24 '13 at 06:23
  • 2
    Just to be sure to capture what all of this means: in C you can write a program where the logic is completely implemented with signal handlers and have the program sit in an infinite loop to wait for an event. This doesn't sound like a very clever implementation of something, but I agree that the language shouldn't prohibit this. In C++ this would be forbidden? – Jens Gustedt Mar 24 '13 at 08:09
0

The rationale for this question with relevance to C++ isn't relevant to C. Section 5.1.2.3p6 states the limits to optimisation, and one of them is:

At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.

Now the question becomes "What data would execution according to the abstract semantics have produced?". Assuming a signal interrupts the loop, the program may very well terminate. The abstract semantics would have produced no output prior to that signal being raised, however. If anything, the compiler may optimise the puts("Hello"); away.

autistic
  • 1
  • 3
  • 35
  • 80
  • To clarify, consider the following: a program with nothing but an empty loop followed by `puts("Hello");` is compiled and executed, `kill` is used to send a signal for the program to exit, and the program gracefully does so by calling exit from the signal handler. Where's the UB, @Deduplicator? As far as I'm aware, the only UB in signals is if the program returns from one of the signals corresponding to computational errors. That's not what happens here, however, since the signal handlers call exit, rather than returning. Please get your facts straight. – autistic Mar 23 '15 at 02:17
  • `exit` executes exit-handlers and does other things, which are not guaranteed to work at all. – Deduplicator Mar 23 '15 at 02:29
  • @Deduplicator Are you trying to tell me that a compiler may not optimise the `puts("Hello");` away, because undefined behaviour might be present in one of the atexit handlers? The consequence of undefined behaviour in an atexit handler is... undefined. How does that stop this optimisation from taking place? – autistic Mar 23 '15 at 02:43