4 ms·
> An infinite loop is not UB. It is well defined. From C11: > An iteration statement whose controlling expression is not a constant expression,156) that perfo
by haberman 4y ago
> An infinite loop is not UB. It is well defined.
From C11:
> An iteration statement whose controlling expression is not a constant expression,156) 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.157)
> 157)This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven.
This makes infinite loops UB unless they fall under one of these exceptions (constant controlling expression, performs I/O, accesses volatile objects or atomics).
- AstralStorm 4y agoNot particularly. It does not allow the compiler to assume true infinite loops can terminate. It only allows the compiler to assume loops with non-constant expressions can terminate. (And a bunch of other exceptions where it cannot.) A true infinite loop has a constant expression as the conditional and cannot be optimized away based on this rule. What this rule allows the compiler to do is to optimize away loops where number of iterations are known ahead of time if it has a non-constant expression condition.
- haberman 4y ago> It only allows the compiler to assume loops with non-constant expressions can terminate. (And a bunch of other exceptions where it cannot.) That is basically what I said: loops can be assumed to terminate, except for an enumerated set of exceptions where infinite loops are allowed. You seem to be defining "true infinite loop" to mean "while(1)" or "for(;;)" exclusively. But "for (int i = 0; i < 1;)" is also an infinite loop, and that one is UB since the controlling expression is not constant. > What this rule allows the compiler to do is to optimize away loops where number of iterations are known ahead of time if it has a non-constant expression condition. If the number of iterations are known ahead of time, then it is not an infinite loop so I don't see how the rule would apply. The rationale for making infinite loops UB is described here: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm Specifically, it allows for transformations like turning: for (p = q; p != 0; p = p -> next) { ++count; } for (p = q; p != 0; p = p -> next) { ++count2; } into: for (p = q; p != 0; p = p -> next) { ++count; ++count2; }
- AstralStorm 4y agoInfinite loop with a constant expression is defined behavior. for (;;) { }; cannot be assumed to have finite number of executions. Therefore, it cannot be optimized away to finite execution. You're showing potentially infinite loops with non-constant expression as condition. for (; i != 0; ) {} can be assumed to have finite number of executions and can be optimized unless i is constant expression.
- haberman 4y ago> Infinite loop with a constant expression is defined behavior. Yes, because a constant controlling expression is one of the enumerated exceptions to the rule against infinite loops. > You're showing potentially infinite loops with non-constant expression as condition. "for (int i = 0; i < 1;)" is an infinite loop, full stop. It is not potentially infinite, it is infinite under all possible executions. It is UB because it does not fall under one of the enumerated exceptions where an infinite loop is allowed. I think we are saying the same thing, the only difference is that you seem to be defining "infinite loop" to only include loops with constant controlling expressions, whereas I am defining it to mean "any loop that does not terminate."