Took me forever to realize this one. I had a for() loop that didn't seem to be running. So I added a debug message: Serial.print(x) and all started to work again. Changed the message to '.', and it didn't work anymore. The pattern didn't catch my attention.
Had to walk away to have the ah-ha moment. Lesson learned, but I'm sure I'll do it again tomorrow.
int x;
outside of a function should be the same as
int x=0;
outside of a function. It might be that they are stored in different sections but this depends on the compiler and the compiler parameters.
Or was x a local variable of a function in your sketch?
Global memory is guaranteed to be initialized to 0 but stack variables are not.
If it's inconsistent output from print, this may be a problem on the receiving side. In some terminals, if you output a character at a time, the terminal doesn't refresh until it hits a newline or a buffer boundary (like every 1KB of input). So sending endless '.' to show progress, for example, doesn't always give the user consistent feedback.
inside of the loop. No other operation (that I could think to use) on x would cause the loop to run. Only a println.
I assumed x was going to be initialized as 0, but that didn't seem to be the case. It was only accidental that I realized sending the value of x over the serial port caused the loop to run. I'm not entirely sure why that was the case, but like I said lesson learned (for now). Don't assume the compiler will initialize your variables.
Were you actually doing no work (with {} there)? If so, the compiler would figure out that nothing was being done three times, and would produce no machine instructions at all. This is one small aspect of the process called optimization: the compiler paraphrases your intent to run as fast as possible using the least memory. It couldn't figure out why you'd want to do nothing three times, so it decided to do nothing zero times instead, if you get me.
Whether you say for (int x... or int x; for (x..., the variable x does not get initialized. These are allocated on the stack if any storage is required, or just maintained in processor registers if the compiler can get away with it.
Isn't it true that initializing a variable without setting a value sets its value to NULL, not zero? If that's true, then there may be a very minor bug in Serial.print() that converts the value to zero when it's actually NULL. I haven't come across any situations where I needed a variable to be NULL in the Arduino world, but in programming in general it's very common.
In the case of an Arduino loop, NULL is probably valid but the condition is immediately false so the loop exits. Arithmetic may not compute, so the work you're doing is rendering no output or result(?)
One, don't use volatile unless you're modifying the variable from an ISR, or it's a hardware register. Trying to defeat the optimizer is like trying to drive a car using only spoons. Instead, turn off the optimizer with command-line options, or trust that it's doing the right thing in 99.999% of the time. For delay loops, code it in assembler for better precision, and/or watch a clock register.
Isn't it true that initializing a variable without setting a value sets its value to NULL, not zero?
Two, there is no distinction between 0 and NULL. The program cannot tell what is initialized and what is not initialized after the fact. The NULL symbol refers to 0. (In C, it's ((void*)0) and in C++ it's just (0), but it is interchangeable and the same thing.) This is not Java.
Does the arduino compiler have optimization like that? (writing out for loops etc) I would always put a =0 fo a for loop just to make sure, and also to help debugging... and understanding.