【问题标题】:GCC implicit alignment problem. (64-bit code)GCC 隐式对齐问题。 (64 位代码)
【发布时间】:2011-02-03 08:03:59
【问题描述】:

如何在 gcc 中明确禁用已定义变量的对齐?
拿这个代码:

typedef struct{
  unsigned long long offset;
  unsigned long long size;
  unsigned long type;
  unsigned long acpi;
}memstruct;

memstruct *memstrx;

这将定义一个大小为 24 字节的结构。
我试着做:

memstrx=(void*)(0x502);

所以

&memstrx[0] 的值应该是 0x502
&memstrx[1] , 0x51A
&memstrx[2] , 0x532

...等等等等。

但事情似乎不对。

相反,

&memstrx[1] 显示地址 0x522
&memstrx[2], 0x542
&memstrx[3], 0x552

...等等等等。

我怀疑 GCC 已经隐式地将结构重新调整为 32 字节(从 24 字节),强制(每个条目的 64 位对齐)。而且我真的不希望这种行为只适用于这种结构。我应该如何告诉 GCC 不对齐该结构?

【问题讨论】:

    标签: c gcc memory-alignment


    【解决方案1】:

    不可以。

    您显示的结构的最小大小是 8*4 = 32 字节。

    sizeof(unsigned long) = 8 在 64 位架构 (Linux) 上

    编辑:如果你会使用

    -unsigned 而不是unsigned long

    • uint32_tuint64_t 而不是 unsigned longunsigned long long

    你会得到预期的对齐。

    【讨论】:

    • “不,它的最小大小不是 8*4 = 32 字节。”是什么意思,结构的大小?
    • Artyom 表示unsigned long 在 64 位机器上是 8 个字节。如果您想要 32 位,请使用普通的 unsigned,或者更好的是使用精确大小的类型(uint32_tuint64_t)而不是大小可能不同的类型。
    【解决方案2】:

    #pragma pack(x) 可以改变 GCC 和 MSVC 的结构对齐限制。

    GCC 使用 LP64 模型进行 64 位构建 - 这意味着 long 和指针是 64 位的。您需要将 32 位字段更改为 unsigned int,或者使用 uint32_t 和 uint64_t 以获得稳定的字段大小。

    #pragma pack(1)
    
    typedef struct{
      unsigned long long offset;
      unsigned long long size;
      unsigned int type;
      unsigned int acpi;
    }memstruct;
    
    #pragma pack()
    

    【讨论】:

      【解决方案3】:

      这是使用 gcc 控制对齐的一个选项:

      http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html

      【讨论】:

      • 这与对齐无关 - 他只是错过了正确的类型
      • @Artyom 在我发布时,该问题已在另一个答案(您的帖子)中得到解决。但是,在我发布时,任何回复中都没有提供我发布的信息。每个答案都会很有用,具体取决于读者/上下文。欢呼
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 2011-01-07
      • 2015-04-03
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 2012-06-12
      相关资源
      最近更新 更多