Arduino: sizeof() function returns weird results for structure with float inside

Created on 28 Mar 2016  路  3Comments  路  Source: esp8266/Arduino

Basic Infos

Hardware

Hardware: ESP-07
Core Version: 2.1.0

Description

When ths following structure is created:

typedef struct packet_t{
  uint8_t a;     // sizeof(uint8_t) returns 1
  uint8_t b;     // sizeof(uint8_t) returns 1
  float c;         // sizeof(float) returns 4
};

the size of it is clarly 6 bytes but the sizeof(packet_t) returns 8 instead.

What is more weird the sizeof the structure below also returns 8:

typedef struct packet_t{
  uint8_t a;     // sizeof(uint8_t) returns 1
  float c;         // sizeof(float) returns 4
};

Another example where sizeof returns 12 instead of 9:

typedef struct packet_t{
  uint8_t a;     // sizeof(uint8_t) returns 1
  float c;         // sizeof(float) returns 4
  float d;         // sizeof(float) returns 4
};

I hope someone can fix that.
Thank you in advance.
Regards,
Greg

Settings in IDE

Module: ?Generic ESP8266 Module?
Flash Size: ?4MB?
CPU Frequency: ?160Mhz?
Flash Mode: ?qio?
Flash Frequency: ?40Mhz?
Upload Using: ?SERIAL?
Reset Method: ?ck?

Most helpful comment

@gosewski

To avoid data structure padding to word boundaries I would use type declaration as follows:

typedef struct __attribute((__packed__)) packet_t{
  uint8_t a;
  uint8_t b;
  float c; 
};

For the above declaration sizeof(packet_t) returns 6.

I saw it used for ESP here. I believe the purpose was to "compress" size of data being sent over serial.

Basing on @igrr's comment above I would use _attribute((__packed__)) with extra caution as this is telling the compiler to align data differently than it is used to normally do :smile: I would also do separate testing when planning to use such code on other platforms / with other compilers.

Krzysztof

All 3 comments

On many architectures, accessing word-sized values is only allowed when these values are aligned to word boundaries. This alignment is automatically done for structure members by the compiler.
https://en.wikipedia.org/wiki/Data_structure_alignment
http://c-faq.com/struct/align.html

@gosewski

To avoid data structure padding to word boundaries I would use type declaration as follows:

typedef struct __attribute((__packed__)) packet_t{
  uint8_t a;
  uint8_t b;
  float c; 
};

For the above declaration sizeof(packet_t) returns 6.

I saw it used for ESP here. I believe the purpose was to "compress" size of data being sent over serial.

Basing on @igrr's comment above I would use _attribute((__packed__)) with extra caution as this is telling the compiler to align data differently than it is used to normally do :smile: I would also do separate testing when planning to use such code on other platforms / with other compilers.

Krzysztof

@igrr Thank you for the information, I didn't know about this "nice" aligment feature. Perhaps it increases the performance of PC class computers but for small microcontrollers the benefit seems to be next to nothing comparing to the pain it introduces.

@krzychb You are right, this structure was meant to pack the data to be send over I2C bus between ESP8266 and Arduino Nano. Thank you for the clue with _attribute((__packed__)). Due to unpredicted results of it, as you mentioned, I decided to add "dummy bytes" to the structure and manually align data in it.

Thank you gents for suport!
Regards,
Greg

Was this page helpful?
0 / 5 - 0 ratings