How does a for loop work internally in terms of the machine language when the expressions are not written. For example
int i=0 , j=1;
for(;;)
How does a for loop work internally in terms of the machine language when the expressions are not written. For example
int i=0 , j=1;
for(;;)
A for
loop with a missing middle expression is an infinite loop.
From section 6.8.5.3 of the C standard:
1 The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: The expression expression-2 is the controlling expression that is evaluated before each execution of the loop body. The expression expression-3 is evaluated as a void expression after each execution of the loop body. If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions; it is reached in the order of execution before the first evaluation of the controlling expression. If clause-1 is an expression, it is evaluated as a void expression before the first evaluation of the controlling expression.
2 Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a nonzero constant.
Because a missing "expression-2" is replaced with a non-zero constant, and because a non-zero value evaluates to true, this gives you an infinite loop.
All the parts of the for-loop are optional:
for(;;)
is an infinite loop (if there are no break
s inside the loop).
The expressions which are not present do nothing.
If the initialisation is absent, nothing is initialised.
If the test is absent, nothing is tested (and the body loops forever unless it contains abreak
, return
, etc.)
If the increment is absent, nothing is incremented.
The for loop contains three clauses. They can be virtually any expression, but the standard way of using it is for(<init>; <loop condition>; <loop variable increment>)
. All of these are optional: if you omit the loop condition, it will be replaced by a constant that evaluates to true. You could for instance replace
for(int i=0; i<10; i++) {
...
}
with
for(int i=0; i<10; ) {
...
i++;
}
for(;;)
is an infinite loop. Any for
loop that has second statement omitted is an infinite loop.
There are basically three ways to get out of an infinite loop, break
, return
and goto
.
In most cases you should use break
or return
, but goto
also has its usage.
If you want to just break out of the loop and continue after it, use break
.
If you want to quit the function that contains the loop, use return
. However, this can be bad practice since it will likely violate the "single exit" practice.
If you want to break out of a nested loop, goto may be appropriate.
And yes, you could exit a loop by calling exit()
or simply make the program crash too, but I think you get the point.
Question from comments
for(i<2; i++; )
This does not make much sense. The first expression i<2
will not affect anything and is likely to be optimized away by the compiler. The second expression i++
will evaluate to false if i
is 0
:
if i
has an initial value of 0
, the loop body is not evaluated at all.
if i
is initially a negative number. The loop iterates until i
reaches the value 0
, the last iteration occurs with i == 0
and the next test will end the loop.
if i
has an unsigned
type and is greater than 0
. The loop iterates until i
reaches the maximum value for its type and wraps to 0
, the last iteration occurs with i == 0
and the next test stops the loop. If i
is not unsigned, arithmetic overflow will cause undefined behavior, which is bad: the loop may stop or continue indefinitely, depending on the compiler choices, or anything else may occur.