Strange compiler behaviour

I have a question on the following simple code block, which, when complied in Arduino IDE for an Uno, does not do what is expected.

In the main void loop(), there is a simple “for-loop” which counts up to maxcount, in this case, 10000000. Naturally, if maxcount is changed to something smaller (eg to 1000), then the void loop() is much quicker.

Here’s the thing - if I insert a statement i2++ after the for-loop, as shown below, the size of maxcount makes no difference.

Why is that? Why does adding i2++ change the speed of the for-loop?

NOTE: If I compile this same code in the Arduino IDE for another processor (I used an Artemis Nano), this does not occur - that is, the speed of the void loop() varies depending on the size of maxcount, regardless of whether the i2++ is there or not… which is what would be expected.

unsigned long i1, maxcount=10000000;
int i2=0;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
 Serial.print("start of the loop ");
 Serial.println(i2);
 
 for (i1=0; i1<maxcount; i1++){
  }
 
 i2++; //If this line is inserted, the "for loop" above does not take any time..
}

Your for loop does nothing, so it's likely that the compiler removes it altogether during the optimization phase and just replaces it with an assignment to i1. As tio why this changes when you add/remove that line ... I couldn't say.

Try adding 'volatile' to the declation of i1.

volatile unsigned long i1;
const unsigned long maxcount=10000000;

'volatile' tells the compiler that you might be doing some screwy stuff involving interrupts or multithreading with that variable, and that it therefore should not do any optimizing with it - it should compile it down to machine code matching your C code. You should then find that this chunk of code behaves the way you would expect.

Thanks for the reply.

Yes, sure enough, making i1 volatile stops the compiler from optimizing the for-loop, but it's still a mystery why adding the i2++ after the for-loop makes any difference to the optimization, since i2 isn't related to the for-loop, or anything else.

Not 100% sure but I think it is outside the loop.

gmq:
... but it's still a mystery why adding the i2++ after the for-loop makes any difference to the optimization, since i2 isn't related to the for-loop, or anything else.

Agreed. Compiler optimisation is something of a black art. I believe the IDE uses the gcc compiler, so it comes down to those guys.