Odd compiler behavior

I loaded a friends ino program from Github which compiles and runs perfectly. However, in reviewing the code I found something I thought should cause the compile to fail. Here’s the code:

unsigned int data[2];
…blah blah blah
data[0] = Wire.read();

data[1] = Wire.read();
…blah blah blah
float humidity = ((data[0] * 256.0) + data[3]);

In this case the array is defined with 2 elements (data[0] and data [1])
but the last line references a data[3] element which has not been defined or initialized.

Why doesn’t this break the compiler?


Because the compiler does do boundary checks only for the initialization but not for the “active” code.
After all data is only a unsigned int* and 3 is just an offset.

You could write i = 3; data[i] = 0; in machine code the latter instruction is exactly the same as data[3] = 0; but the compiler won’t know or care about the violation.

Thank you ScuffR. For the record, this code does not cause a runtime error either. It would seem like data[3] would return a null and the resulting equation would be (for instance) 5 + null which I would have thought would through an error.

In C/C++, data[3] where 3 is past the length, just reads the next memory location after the locations where the array data is stored. As @ScruffR said above, all the compiler is doing is taking the base address of the data array and adding 3 times the size of an element of that array to get a new memory address and then reading from there.

If you compile locally using gcc you can even figure out what might be in that location past your array. This type of bug is obscure and difficult to track down and leads to lots of swearing in my experience.

Thanks bko. That makes sense. I just happened to see it - who knows how long its been in use :slight_smile: