gcc,枚举没有按预期打包

orf*_*uit 0 c gcc

枚举的大小没有包装,为什么呢?

typedef enum{
    STATE_IDLE = 0,
    STATE_RUN,
}State_t;

#pragma pack(1)
struct {
    char c;             //1
    State_t State;      // should be 1 but is 4
    uint32_t Time;      //4
    sCB_t CB;           //4

}App;
#pragma pack()

int main()
{
    printf("Size bytes: %u\n", sizeof(App));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

以上将输出

Size bytes: 13
Run Code Online (Sandbox Code Playgroud)

我在x86上使用CodeBlocks 16.01和gcc

C:\Program Files (x86)\CodeBlocks\MinGW\bin>mingw32-gcc.exe --version
mingw32-gcc.exe (tdm-1) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)

也是__attribute__((packed))不行,经过一番挖掘我发现#pragma相当于.

Sta*_*irl 5

#pragma pack不会影响数据类型的大小.它的目的是去除结构中的填充.

对于x86上的GCC,枚举大小为4个字节(并且在其他平台上具有不同的大小).如果你需要缩短它们,有两种方法,都是非标准的:

  • 使用-fshort-enumsflag - dangerous,因为这会更改所有枚举的ABI.基本上你永远不应该使用它.
  • __attribute__ ((__packed__))在声明枚举时使用,仅对该类型实现相同的效果.

您可以这样声明:

typedef enum __attribute__((packed)) {
    STATE_IDLE = 0,
    STATE_RUN,
} State_t;
Run Code Online (Sandbox Code Playgroud)

注意:您提到的__attribute__((packed))不适合您,但我认为您使用的不正确.我能够为你的结构获得10个字节的大小.