Различные компиляторы по умолчанию выбирают различный размер для типа enum. Например, если размер значения перечисления умещается в байт, компилятор IAR Embedded Workbench под такие значения enum будет использовать 1 байт. Компилятор GCC на платформе ESP-IDF в тех же условиях будет отводить под значения enum не 1, а 4 байта.
Отличающееся поведение компилятора на разных платформах может приводить к неприятным ошибкам. Рассмотрим простой пример: перечисление TPacketType и структуру TMsgHeader, в одном из полей которой используется это перечисление:
typedef enum
{
PKT_MESSAGE_GENERIC = 0x05,
PKT_BEACON = 0x06,
PKT_ACKNOWLEDGE = 0x0C
}TPacketType;
#pragma pack(push, 1) typedef struct _TMsgHeader
{
TPacketType PktType;
TPktFlags PktFlags;
uint16_t CallDst;
uint16_t CallSrc;
uint8_t PktNum;
uint8_t BodyLen;
uint16_t BodyCrc;
uint16_t HeaderCRC;
}TMsgHeader; #pragma pack(pop)
Несмотря на наличие директивы #pragma pack(push, 1) для структуры TMsgHeader, поле TPacketType PktType у компилятора GCC будет размером 4 байта, а у компилятора IAR 1 байт.
Принудительно установить размер типа перечисления в 1 байт для GCC поможет директива __attribute__((packed)):
typedef enum __attribute__((packed))
{
PKT_MESSAGE_GENERIC = 0x05,
PKT_BEACON = 0x06,
PKT_ACKNOWLEDGE = 0x0C
}TPacketType;
Теперь размер структуры TMsgHeader и у GCC, и у IAR будет одинаковый.
[Ссылки]
1. How do I set the size of an enumerated type? site:forum.embeddedethernet.com. 2. Forcing enum to be of a specific size site:eevblog.com. |