for Loops and compilers

For example, in

for (j=0; j<N; j++) for (i=0; i<(j+2); i++) { ... }

, does the C++ language standard require the compiler to evaluate (j+2) inside the i loop? If not, roughly what percentage of C++ compilers would evaluate (j+2) before the i loop? (I have always taken pains not to write such code.) What about Visual C++?
[351 byte] By [aruzinsky] at [2007-11-20 7:07:23]
# 1 Re: for Loops and compilers
Hi.

I'm not sure if I understand your question. The term (j + 2) will be evaluated inside the second for loop at every iteration. At the beginning, j is 0, so the second for will execute for i = 0 and i = 1. It will not execute for i = 2, because it will evalute (j + 2) = 2. At the second iteration, j is 1, so the second for loop will execute for i = 0, i = 1 and i = 2, but not for i = 3, because it'll evaluate (j + 2) = 3. It goes on...

Is that it?
ltcmelo at 2007-11-9 1:17:32 >
# 2 Re: for Loops and compilers
I think the OP might be asking about the types of optimizations a compiler might make, for example, to avoid repeated calculations of (j+1) when the value of J hasn't changed (which would be wasteful).

If so, then you can examine the assembly output of the compiler to determine the answer.

But why do you care about such optimizations? Have you profiled the code, and proved to yourself that an optimization like this is needed?

Mike
MikeAThon at 2007-11-9 1:18:32 >
# 3 Re: for Loops and compilers
By looking at the algorithm, it hardly matters.

You have a two dimensional loop which has a quadratic computational complexity. Within the inner loop, any good compiler will handle the addition of 2 to the index j in an efficient fashion. The handling of j in the inner loop will be linear. It will not be computed at every test within the inner loop, but rather once at the top of each inner loop. Therefore adding 2 to j will be relatively insignificant pertaining to the total run-time.

Sincerely, Chris.
dude_1967 at 2007-11-9 1:19:33 >
# 4 Re: for Loops and compilers
...and for those who can't stand but to know what that optimization turns out to be....

lea ebx, DWORD PTR [edi+2]

where edi contains j, the outer loop counter, and the subsequent test on ebx controls the loop.

This seems reasonable assembler assuming something of substance is happening to keep registers busy inside the loop.

On the other hand, if you declare a register int to store j+2, and use that as the limit for the interior loop, the compiler does honor that (by storing the value in ebx here).

Speed difference can't be measured until the interior loop climbs into the millions. Frankly, if the performance difference were of any import, you would be considering an assembler optimization, and if not - the compiler's doing fairly well.
JVene at 2007-11-9 1:20:33 >