使用属性模拟#pragma pack(n)

时间:2016-09-09 08:59:02

标签: c memory-alignment pragma

为了能够执行一些系统的代码转换,我想在我的代码中删除#pragma pack指令,并用本地属性替换它们,例如packed, aligned(n)

但是,我得到的行为并不完全相同:sizeof有效,offsetof会产生不同的结果。这是一个例子:

#include <stddef.h>
#include <stdio.h>
#include <stddef.h>

struct WITH_ATTRS {
  char c;
  double d;
} __attribute__((packed,aligned(4)));

#pragma pack(4)
struct PACK4 {
  char c;
  double d;
};

int main() {
  printf("sizeof(WITH_ATTRS) = %zu\n", sizeof(struct WITH_ATTRS));
  printf("offsetof(WITH_ATTRS, d) = %zu\n", offsetof(struct WITH_ATTRS, d));

  printf("sizeof(PACK4) = %zu\n", sizeof(struct PACK4));
  printf("offsetof(PACK4, d) = %zu\n", offsetof(struct PACK4, d));
  return 0;
}

GCC(5.4.0)和Clang(3.8.0)都为我输出了同样的东西:

sizeof(WITH_ATTRS) = 12
offsetof(WITH_ATTRS, d) = 1
sizeof(PACK4) = 12
offsetof(PACK4, d) = 4

所以,我从中理解的是:

  • __attribute__((packed,aligned(4)))在字段cd之间没有间隔,但在结构的末尾,确保它是4的倍数(因此sizeof == 12);
  • #pragma pack(4)cd之间留下3个字节的间隔,同时产生sizeof == 12

是否有通用的方法来获取PACK4的布局,但不使用编译指示?

0 个答案:

没有答案