int x; != int x=0;

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. :wink:

I am not sure if I understand your message.

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?

If I can guess what you're saying...

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.

Okay, so here is a more detailed explanation.

for (int x; x<3; x++) {}

would not run, unless I used:

Serial.println(x)

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.

There is work being done in the loop. I just ignored it for the post since it did not matter what operations were in there, except for a serial print.

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(?)

I would always initialize counter variables (in this case with a zero) unless this is a global variable, but even then it is a good idea.

And if you don't use or modify the variable inside the loop, then it is a good idea to make it volatile at some compiler optimization levels...

so in your case:

for (volatile int x=0; x<3; x++) {}

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.

The trickery of math and programming =(

No one said the word "undefined" yet, so I'm jumping in:

int x; gives x an undefined value in C, and the value 0 in C++.

If you use:-

for (volatile int x=0; x<3; x++) {}

Then x is ONLY defined for use inside the for loop.
Outside the loop you can define another variable called x and it will have a separate life.

I think this is the root of the misunderstanding here.

Mike, is that because you're defining it as volatile or because you're defining it in the loop definition? (or both?)

Because it's in the loop definition. It dies at the } with most compilers.

(As I mentioned before, 'volatile' doesn't make a difference to lifetime but makes no sense for local variables like this.)

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.

Does the arduino compiler have optimization like that? (writing out for loops etc)

You should initialize variables used in loops. Not including the initializer is not an "optimization," it's a programming logical error.