Loop problems (for & while).

I’ve seen a few issues on loops, on this forum. However none seem to match my issue. My code is quite simple. I’m trying to find out how long it takes to count to 232.

uint32_t i = 1;

void setup() {
  Serial.begin(9600);
  Serial.print("\nStarting at: ");
  Serial.println(i, HEX);
  
  while (i != 0) {  // Start counting up and see how long it takes
    i++;
  }
  
  Serial.print("\nEnding at: ");
  Serial.println(i, HEX);
}

However, the above code fails to execute the loop. As if “i” is equal to “0” when tested in the while loop. When I declare the variable as volatile, the loop executes (below). However, I do not understand why this declaration is necessary.

volatile uint32_t i = 1;

void setup() {
  Serial.begin(9600);
  Serial.print("\nStarting at: ");
  Serial.println(i, HEX);
  
  while (i != 0) {  // Start counting up and see how long it takes
    i++;
  }
  
  Serial.print("\nEnding at: ");
  Serial.println(i, HEX);
}

I have a work-around, so am not desperate for an answer. However, I would like to know why this is so.

i believe the optimized optimizer out the while loop because the variable i wasn't used anywhere that it's value wasn't predictable

Thanks. I've taken a look at your response (and and those of others) and I believe I understand what is happening. In order to verify my understanding I re-ran the code, inserting the snippets below inside the loop. Please take a look at my findings and let me know if i've overlooked anything.

ctr = function(i);
Per the above sketch, this snippet forces the loop to remain because the value of "i" is "utilized" to determine the output of function(). The details of what the function might do to/with "i" are unknown, therefore we better pass 'i" in to the function. AKA don't optimize out the loop.

ctr = sq(i);
This snippet also worked. While this is a built in function, I'm assuming that "i" needs to be passed anyway. Maybe because someone may overload the SQ() function.

digitalWrite(3, i);
Not sure what happened here but the loop did not run (loop optimized out). We are passing "i" to a function again, as in the first two snippets. Perhaps as the function does not return a value, and therefore has no direct impact on software flow, the optimizer assumes it can remove the loop.

i = sq(ctr);
or
i = !digitalRead(3);
or
i = 1 + random();
OK... These three snippets also worked. In these cases, "i" is not "utilized" by the the snippet. However, the value of "i" is being modified in each case and the modification of the value could change the software flow through the loop. (Per Arduino) The value of "i" was no longer predictable, thus the loop had to remain.

i agree with your comments.

don't understand the issue with digitalWrite(). i wouldn't have thought a return value matters.

Oops. Bad note taking... digitalWrite(3, i); enforces the loop too.

Interestingly delay(1), within the loop, keeps the loop in place as well. As it should, I suppose. It's really just my foolish use of a null loop that does nothing more than use CPU cycles that doesn't work.

Many thanks.