Same code, different results. Ver 0022.

(*Almost the same code)

Sorry, I know ver 22 is no longer supported but I am not ready to port everything over 1.x yet.

Anyway, I was troubleshooting some code that I thought was fairly straight forward and discovered some unexpected behavior. I tried to search this out, but I'm not even really sure what I would search.

I have this code that gives me errant results, but will give me the correct result by changing a couple simple things that I would not expect should make any changes.

I guess one question that comes to mind is, if a variable gets re-declared, does it need to be initialized explicitly to zero? I don't think I've ever worried about this in the past and haven't had trouble.

I narrowed the troublesome code down, and simply swapping the last two lines makes it work or not work. Also, simply initializing Checksum to zero seems to also make it work correctly, but I was under the impression a byte datatype would initialize to zero automatically.

void setup() {
  Serial.begin(9600);     //temporarily using serial to report to computer for testing.
}


void loop() {
  char LcdPacket[]=">00wrd0714Hello World";  //Correct result with this array is always 95.
  //char LcdPacket[]=">0";                   //Using this shorter array still has the same problem. (Correct result is always 30.)
  byte LcdCharNum = 1;                       //Starting with 1 to ignore ">".
  char LcdChar;
  byte Checksum;                             //Initializing this to = 0, will give correct results.
  LcdChar = LcdPacket[LcdCharNum];
  while (LcdChar != '\0') {
    Checksum = Checksum + LcdChar;
    LcdCharNum = LcdCharNum + 1;
    LcdChar = LcdPacket[LcdCharNum];
  }
  //Swapping the two lines below will give different results. delay on top gives correct results: 95.
  Serial.println(Checksum,HEX);
  delay(2000);
}

but I was under the impression a byte datatype would initialize to zero automatically.

No un-initialize var's of any type get a "random" value. Global's however ,,,,,

Mark

You can have multiple versions of the IDE on your PC. That would allow you to try the code in a newer version without abandoning the old version.

...R

I was under the impression a byte datatype would initialize to zero automatically

Only if declared with global scope or declared as static within a function. Otherwise its value is not defined.

If it was random, then the sketch would almost never work correctly. Notice it works fine when the delay is placed before the serial print.

Somehow the placement of the delay is affecting outcome.

Also, serial printing the variable, after declaring it, returns 0, and not a random value.

The Arduino documentation doesn't make any caveat about variable scope, with regards to initializing, and basically implies initializing to 0 is the same as not initializing.

Is there another piece of documentation that mentions global vs local and declarations?

I previously had used mostly global variables. This time I'm using almost all local variables, so maybe this is why this is becoming an issue.

Robin2:
You can have multiple versions of the IDE on your PC. That would allow you to try the code in a newer version without abandoning the old version.

...R

Good to know. Thanks. I will eventually have to bite the bullet.

The Arduino documentation doesn't make any caveat about variable scope, with regards to initializing, and basically implies initializing to 0 is the same as not initializing.
https://www.arduino.cc/en/Reference/VariableDeclaration

From the page linked to - my emphasis

Variables may be initialized (assigned a starting value) when they are declared or not. It is always good programming practice however to double check that a variable has valid data in it, before it is accessed for some other purpose.

All variables declared within a block of code are automatic by default.
An uninitialized automatic variable has an undefined value until it is assigned a valid value of its type.

see: Current C standard PDF (3.61 MiB): section 6.2.4, Storage durations of objects

Interesting facts about initializing globals and statics Shouldn't I initialize all my variables?

UKHeliBob:
From the page linked to - my emphasis

Yes, I read that, and if I "double check" that the variable has valid data, it does, and is zero as would be expected. The document doesn't say to initialize every variable, and in fact, it implies initialization is not necessary if the desired initial value is zero.

What I would like to know, (and would have edited my original post to say so, but it has a limit of 1 post every 5 minutes), is more why does the placement of the delay alter the result so dramatically.

Is it related to the Serial.print being there. (Obviously I need the serial in order to see the results.)

The link about initializing globals is very interesting, and it suggests it would save space to not initialize variables if they would be initialized to zero.

So in general, variables should only be explicitly initialized if the initial value is non-zero.

But I'm not sure if this pertains to local and global variables or only global.

I believe that the local variable is allocated to a register, so you are using the previous content of that register, if you don't initialize a local variable. Depending of the function running before and its register usage, you will get different results.

why does the placement of the delay alter the result so dramatically.

Because the value of of an uninitialized automatic variable will be whatever was left in the storage location by any code that ran previously (whether this is a register, or a bit of RAM on the stack, or perhaps something else.) It's "random" in the sense that you as programmer probably can't predict it, but not random at all in a statistical or cryptographic sense. It IS entirely likely that it would change between different versions of a compiler (as they change register allocation algorithms, for instance.)

Thank you for the replies.
They make sense to me, but then this brings up another question:

When I use Serial.print(Checksum,DEC), immediately after the declaration, the serial monitor shows the uninitialized value as "0", and the results of the remaining code, end up being correct. Does the act of using Serial.print on the uninitialized variable, cause it to then get initialized to zero?

Also, shouldn't the documentation then say that initialization of local variables must be explicit, even when the desired initial value is 0?

Loudhvx:
When I use Serial.print(Checksum,DEC), immediately after the declaration, the serial monitor shows the uninitialized value as "0", and the results of the remaining code, end up being correct. Does the act of using Serial.print on the uninitialized variable, cause it to then get initialized to zero?

It very well might have just that effect.

Loudhvx:
Also, shouldn't the documentation then say that initialization of local variables must be explicit, even when the desired initial value is 0?

The Arduino documentation should say a lot of things that it doesn't. Good luck trying to get hold of anyone to get it changed. They don't seem to care much so we're stuck with it.

Shouldn't the documentation then say that initialization of local variables must be explicit

No, the Arduino documentation should not duplicate the entire C/C++ language specification.

Calling Serial.print() could change which register is used for the variable...

westfw:
No, the Arduino documentation should not duplicate the entire C/C++ language specification.

Calling Serial.print() could change which register is used for the variable...

Thanks again Westfw.

Obviously it need not duplicate the language spec, but it shouldn't contradict it either.
It would be fine if it was silent on the issue, but it's not silent, it's misleading.

I'm not complaining, but just pointing it out to help anyone else who may have encountered strange results.

I assume bugs in my sketches are entirely my fault. But when things don't really act as the documentation describes, then it's much harder to locate bugs. These cost me half a day.

Declaring Variables

Before they are used, all variables have to be declared. Declaring a variable means defining its type, and optionally, setting an initial value (initializing the variable). Variables do not have to be initialized (assigned a value) when they are declared, but it is often useful.

int inputVariable1;
int inputVariable2 = 0; // both are correct

Both are certainly not always correct.

A variable does NOT need to be initialized if it will be assigned a value befor it is used.

Obviously it need not duplicate the language spec, but it shouldn't contradict it either.

Where does the contradiction occur ?

The wording (and example) can be interpreted to mean that assigning it to 0 is the same as not assigning it a value. Obviously, now I see it doesn't.

A mention of the distinction would have been helpful.

Variables do not have to be initialized (assigned a value) when they are declared, but it is often useful.

int inputVariable1;
int inputVariable2 = 0; // both are correct

A variable does NOT need to be initialized if it will be assigned a value befor it is used.

(continuing, now that I'm at a keyboard...)

int inputVariable;
 do {
    inputVariable = Serial.read();
      :
   } while (inputVariable != CH_RETURN)

Is quite common, and perfectly correct.
Put another way, a variable declaration that doesn't include an initializer is always a "correct declaration", but it might not do the correct thing WRT your program. Sort of like "pi = 4;" is a fine and correct assignment statement.

westfw:
...Put another way, a variable declaration that doesn't include an initializer is always a "correct declaration", but it might not do the correct thing WRT your program. Sort of like "pi = 4;" is a fine and correct assignment statement.

Yes, I like that analogy. :slight_smile: