Search code examples
c++floating-pointavrsizeofatmega

sizeof(float) giving wrong result on atmega2560


I'm working with the atmega2560 controller and avr-g++. I'm debugging code that works on my Ubuntu 18.04 host (when compiled with g++) but not on the atmega2560. I thought it might be a problem of different data type sizes, and used this code to investigate (also given below):

int integerType;
float floatType;
double doubleType;
char charType;

printf("Size of int: %ld bytes\n",sizeof(integerType));
printf("Size of float: %ld bytes\n",sizeof(floatType));
printf("Size of double: %ld bytes\n",sizeof(doubleType));
printf("Size of char: %ld byte\n",sizeof(charType));

The results on the host look ok but the avr-g++ compiled code on atmega2560 gives wild sizes for the different data types:

g++:

Size of int: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
Size of char: 1 byte

avr-g++:

Size of int: 2 bytes
Size of float: 41680900 bytes
Size of double: 43253764 bytes
Size of char: 44957697 byte

which is completely unrealistic. What could be the reason for this?

update

It was suggested that I try %zu instead of %ld to print the std::size_t outputs from sizeof(...). This, unfortunately, didn't work, and the output looks as follows:

Size of int: Size of float: Size of double: Size of char: 

Solution

  • On the atmega2560, an integer is 2 bytes. So each of your calls to printf is passing the format string, followed by a 2-byte integer.

    But the format string specifies %ld, which is a 4-byte long integer; so printf is expecting a 4-byte value on the stack. It is therefore reading bytes from the stack that weren't pushed there by the calling function; these bytes could have any value whatsoever.

    If you had printed the values in hexadecimal with %lX, you would have seen the expected size in the low-order two bytes. For example, 41680900 is 0x027C0004, and you can see the size of a float in that 0004. The 027C is effectively random noise.

    To fix this, use %d instead of %ld. This will work on your Ubuntu host (with 4-byte integers) and your atmega2560 (with 2-byte integers).

    Perhaps even better is to use %z, as explained in chux's answer, in case the size of a sizeof is not the same as the size of an int.