Not exactly what you asked for, but C11 added this bit that was not there in C99:
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, may be assumed by the implementation to terminate.
And C++11 added this bit that wasn't there in C++03:
A loop that, outside of the for-init-statement in the case of a for statement,
- makes no calls to library I/O functions, and
- does not access or modify volatile objects, and
- performs no synchronization operations (1.10) or atomic operations (Clause 29) may be assumed by the implementation to terminate.
[Note: This is intended to allow compiler transformations, such as removal of empty loops, even when termination cannot be proven. -- end note]
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, may be assumed by the implementation to terminate.
And C++11 added this bit that wasn't there in C++03:
A loop that, outside of the for-init-statement in the case of a for statement, - makes no calls to library I/O functions, and - does not access or modify volatile objects, and - performs no synchronization operations (1.10) or atomic operations (Clause 29) may be assumed by the implementation to terminate.
[Note: This is intended to allow compiler transformations, such as removal of empty loops, even when termination cannot be proven. -- end note]