gcc,枚举没有按预期打包

时间:2018-04-08 22:37:21

标签: c gcc

enum的大小没有打包,为什么会这样?

var textByLine;

function readTextFile(file, cb) {
  return new Promise((resolve, reject) => {
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", file, false);
    rawFile.onreadystatechange = function() {
      if (rawFile.readyState === 4) {
        if (rawFile.status === 200 || rawFile.status == 0) {
          resolve(rawFile.responseText);
        }
      }
    }

    rawFile.send(null);
  });

}

readTextFile('mytext.txt').then((text) => {
  textByLine = text.split("\n");
});

// ... rest of you code ...

以上将输出

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;
}

我在x86上使用CodeBlocks 16.01和gcc

Size bytes: 13

同样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. 无效,经过一番挖掘,我发现__attribute__((packed))等效。

4 个答案:

答案 0 :(得分:5)

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

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

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

您可以这样声明:

typedef enum __attribute__((packed)) {
    STATE_IDLE = 0,
    STATE_RUN,
} State_t;

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

答案 1 :(得分:0)

在我的系统上使用gcc(x64_64 Ubuntu),类型State_t的大小为4个字节。

确定何时定义State_t。将#pragma pack(1)应用于稍后定义的结构类型不会影响State_t

(枚举类型的大小是实现定义的.gcc的文档应该告诉你它是如何完成的。)

答案 2 :(得分:0)

我找到了一个更完整的答案,万一有人需要。

为了正确包装,必须首先放置较大的类型(即降低内存地址),请参见此图片。

由于我已经为进一步的嵌入式进行了一些测试(将被重新编译),我不会再进一步​​研究,这至少在我的机器上,Win 7 Ultimate 64位,i5-4200 CPU。

enter image description here

答案 3 :(得分:0)

即使在旧版gcc中也可以使用

#if defined(__MINGW32__)
#   define __is_packed       __attribute__((__gcc_struct__, __packed__, __aligned__(1)))
#else
#   define __is_packed       __attribute__((__packed__, __aligned__(1)))
#endif