【问题标题】:Am I misunderstanding __attribute__ ((packed)) in GCC?我是否误解了 GCC 中的 __attribute__ ((packed)) ?
【发布时间】:2015-01-08 11:40:44
【问题描述】:

我正在尝试以下操作,在 win32 上使用 gcc。

#include <stdio.h>

struct st { char c; int x; } __attribute__ ((packed));

int main() {
    printf("%d\n", sizeof(struct st));
    return 0;
}

我希望打印的值为 5,但它是 8。

但是,我得到 5。

#include <stdio.h>

#pragma pack(1)
struct st { char c; int x; };

int main() {
    printf("%d\n", sizeof(struct st));
    return 0;
}

我的程序一定有问题,但我看不出是什么。 我已经阅读了gcc's manual 和几个关于这个的问题,但我仍然感到困惑。有什么提示吗?

此外,从对 SO 的这些问题的回答中,我了解到我不应该对 marshalling 使用打包结构,而且我可能不会经常使用它,但我仍然想了解我无法做到的事情看到这么短的节目。

注意:gcc-4.9.2 和 gcc-4.8.4 都会出现问题。

【问题讨论】:

  • 对我来说它有效。 codepad.org/Zrilgx9t
  • @Jayesh 好的,那么,我有来自mingw-w64 的 gcc-4.9.2,也许是这个版本的问题?
  • 首先,你应该写 %lu 而不是 %d
  • @yakoudbz 这将在编译时抛出警告:warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'unsigned int'。但是,我同意 %d 应该由 %u 代替。当然也解决不了问题。
  • @Nivak 可能会也可能不会。但是你在这里寻找它gcc.gnu.org/bugzilla/show_bug.cgi?id=52991

标签: c gcc struct


【解决方案1】:

你的属性放错了地方 - 试试这个:

struct st { char c;
            int x __attribute__ ((packed));
          };

根据 gcc 手册中的示例,这将导致 x 被打包,使其紧跟在 c 之后。

当然,您一开始就不应该这样做,因为您的代码会在某些架构上中断,即使没有中断,也可能会导致性能损失。

【讨论】:

  • OP 的代码对我有用,所以将 __attribute__ ((packed)) 放在最后应该没问题
  • @Gopi,我不确定:packed 属性指定 变量或结构字段 应该具有最小可能的对齐方式——变量一个字节,并且字段一位,除非您使用对齐属性指定更大的值。
  • @AlterMann 和@PaulR 根据我在网上找到的所有内容,它应该在结构之后工作(甚至在之前,如struct __attribute__ ((packed)) st { char c; int x; };)。但是看到上面Jayesh的评论,我认为这是一个错误。
  • @PaulR 我只会将其用于编组,但在寻找答案时我发现实际上即使这样做我也不应该......我对此很好,但我想了解这个属性是如何工作的,以防万一。
  • packed 属性可以放在变量或结构字段上,记录在这里:gcc.gnu.org/onlinedocs/gcc/… 或者它可以放在结构上,记录在这里:gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
【解决方案2】:

在我的环境 Centos 5.11 (64bit) 上运行良好 为您提到的第一个案例打印 5。

gcc 版本 4.9.1 (GCC)

gcc 文件.c

./a.out 

5

【讨论】:

  • 根据Jayesh的link above,是mingw的问题。我使用 mingw-w64 在3264 bits 中重现了与 gcc-4.8.4 或 gcc-4.9.2 相同的问题。无论如何感谢您的回答。
猜你喜欢
  • 2012-01-24
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 2021-09-21
  • 2012-07-31
  • 2010-10-24
  • 1970-01-01
相关资源
最近更新 更多