Why do compilers seems to be polite toward loops that do nothing and do not eliminate them?
Does the C standard require loops to take some time?
Example, the f
No, time spent does not count as observable behaviour to be protected by the as-if rule:
[C++14: 1.8/5]:
A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).
[C++14: 1.5/8]:
The least requirements on a conforming implementation are:
- Access to volatile objects are evaluated strictly according to the rules of the abstract machine.
- At program termination, all data written into files shall be identical to one of the possible results that execution of the program according to the abstract semantics would have produced.
- The input and output dynamics of interactive devices shall take place in such a fashion that prompting output is actually delivered before a program waits for input. What constitutes an interactive device is implementation-defined.
These collectively are referred to as the observable behavior of the program. [ Note: More stringent correspondences between abstract and actual semantics may be defined by each implementation. —end note ]
Those loops can be legally optimised out and, indeed, there are scenarios in which the standard makes deliberate attempts to make doing so even easier:
[C++14: 1.10/24]:
The implementation may assume that any thread will eventually do one of the following:
- terminate,
- make a call to a library I/O function,
- access or modify a volatile object, or
- perform a synchronization operation or an atomic operation.
[ Note: This is intended to allow compiler transformations such as removal of empty loops, even when termination cannot be proven. —end note ]
Your compiler may in fact be being "polite" in noticing that the intent of the loop in these programs appears to be in slowing down the emission of repeated text output. :)
There is no minimal execution time for a C or C++ executable because execution time depends on many platform specific issues such as:
Some processors support multiplication, others don't. The processors that don't support multiplication would take longer to execute a program than a process that has multiplication instructions. Same with floating point.
The internal operating speed of a processor varies. There is a common unit of time measurement called a "clock cycle". Most processor vendors specify the duration of an instruction in clock cycles. This measurement may be difficult due to internal support, such as cache management.
Some processors have logic that can optimize the execution of instructions, or instruction patterns. One optimization is branch prediction.
Many platforms have interrupts. For example, there may be a "system tick" interrupt which allows the operating system to know when to switch execution to another program. Some are not so periodic, such as when I/O occurs. A minimum execution time cannot be guaranteed when the program gets interrupted.
Stating a minimum execution time would play havoc with the C and C++ language portability. Some platforms would want to execute code faster than the minimum time. Other platforms may not be able to achieve a minimum execution time (but they could benefit from a high level language like C).
Also, how would the time be measured?
Does the minimum execution time apply for delay loops or polling?
You did not specify the compiler, but let's assume it's gcc
.
gcc does not remove empty loops, at least not according to the documentation. It contains the following text:
Historically, GCC has not deleted “empty” loops under the assumption that the most likely reason you would put one in a program is to have a delay, so deleting them will not make real programs run any faster.
However, it can remove empty loops if they are "emptied" by the optimizer, that is, if the loop contains code that the optimizer can move outside the loop, and the resulting loop is empty.
It is not clear from the documentation if this is still true in the most recent version. The manual mentions "historically" without specifying why. If you update your question with information about your exact platform and compiler, maybe a better answer can be given.
No, there is no guarantee: (quotation from N1570, 5.1.2.3 Program execution)
1 The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
Anyway, the C standard only specifies the behaviour of your program when it is executed on an abstract machine, which can have infinite memory and/or CPUs.