I can have something like:
for (unsigned i = 0; i < get_length(object); ++i) {
...
}
where I know for sure that get_length(object) will not change during the loop lifetime, or I can convert it to:
const unsigned length = get_length(object);
for (unsigned i = 0; i < length; ++i) {
...
}
Maybe oftentimes the compiler can't know for sure whether get_length(object)
will indeed not change, so it will evaluate it at every loop, so probably the second form is better, although it is more cumbersome to the eye?
It is debatable whether the first or second form is easiest on the eye.
In any case, with the second form, we make sure that the compiler will only call get_length()
once. I guess that most experienced programmers will prefer this form if the function is indeed intended to return a constant for the duration of the loop, because the second form conveys this assumption by itself.
In the first form, the compiler might in simple cases be able to deduce that get_length()
will be constant and thus only call it once. However, it seems at least GCC is not that smart yet. Godbolt link with optimization level -O3
.
The linked assembler code may be a bit difficult to read, but in f1
, notice that instruction jne .L15
in line 37 which jumps to line 21 which is the beginning of the inlined code corresponding to my example implementation of get_length()
. Thus the code corresponding to get_length()
is in this case executed for every iteration of the loop.
Perhaps the compiler could better optimize an even simpler example or a future version of the compiler or a different compiler could optimize this example. In any case, by using the second form we can avoid such speculation and having to look into compiled assembly code.
This example and analysis should illustrate the benefit of the second form.