So I was bored and curious and wanted to see the difference in the HEX file opcode between two very simple sketches, but to my surprise they are identical and I'm not sure why.
First Sketch:
void loop() {
int a = 0;
for (int i; i < 10; i++)
{
a++;
}
}
Second Sketch:
void loop() {
int b = 0;
b++;
}
I'm using IDE 1.8.13 and the Export Compiled Binary option. And then comparing the two HEX output files using a diff tool but they are identical. I even tried just compiling a new completely blank sketch that contains nothing in the loop() which also gives the same identical output.
So the only thing I can think of is that maybe the compiler knows these are both useless and perform no useable action so it just doesn't even bother to build the assembly?
robriv:
So the only thing I can think of is that maybe the compiler knows these are both useless and perform no useable action so it just doesn't even bother to build the assembly?
Plausible. Try printing the data you calculate to the serial monitor. That'll force the compiler not to optimize your code away.
'Dead code elimination'. The compiler is very good at determining what code actually has some effect on the program, and will remove anything that has no visible effect. In both your cases, since you never use the value of the variables, the compiler gets rid of them.
As someone said, you need to use them in a way that the compiler can't get rid of. Serial.print() is an easy way to do this.
To cut down on the noise in the serial monitor, you could move the code to the 'setup()' function.
void setup() {
int a = 0;
for (int i; i < 10; i++)
{
a++;
}
Serial.println(a);
}
void setup() {
int a = 0;
for (int i; i < 10; i++)
{
a++;
}
Serial.println(a);
}
might very well end up being implemented 'as if' you had written it as:
void setup() {
Serial.println(10);
}
The compiler is allowed to optimize the code any way it likes so long as all the 'observable results' are the same. Since you don't use the values of 'a' in the loop, the compiler doesn't have to do all that.
The compiler can take advantage of all kinds of subtleties of the C++ standard, and can produce some very non-intuitive results that only make sense if you very carefully read the standard. In particular, any kind of accidental 'undefined behavior' in your code can bite you HARD.
FOR EXAMPLE, in your own code here, the value of 'i' is uninitialized! Using an uninitialized variable is 'undefined behavior', and the compiler is literally allowed to do ANYTHING in that case - it does not have to produce a program that 'makes sense'.
It could end up essentially using the following logic:
i is uninitialized
using i is therefore forbidden.
therefore the compiler can ASSUME that that code is unreachable.
therefore the compiler can just leave it out completely, INCLUDING the 'Serial.println()'!
You can't even say 'Well, it will end up printing SOMETHING, right?'. Nope! Undefined behavior contaminates the entire program - if any part of the program is undefined, you can't assume that any part of it will do anything as you expect.
Something else you can do, instead of printing the variable, is to declare the variable as volatile. That tells the compiler that the variable may be accessed by something outside of your code and therefore not to optimize it away.
Thanks folks, I changed each to just do a digitalWrite(LED_BUILTIN,HIGH) and second sketch with LOW and that produced 2 different HEX files where you can clearly see the OPcode change for the HIGH and LOW respectively. I didn't think the compiler was actually that smart, I chased it for a while. It definitely cured my boredom for today wasting my time on this for no real reason other than curiosity haha..
Another answer to the Title (and which is completely consistent with the other advice here) is that two different programs CANNOT have identical Hex files.