我有一个C联合体,有许多字段,很可能在不同的平台上有不同的大小:
union foo {
int a;
wchar_t b;
bar *c;
baz d;
}
现在我想为这个联合添加一个char数组,这个数组与我可以实现的一样大,没有它会导致整个联合变大。
之类的东西union foo {
...
char z[sizeof(union foo)];
}
当然,除了不会编译,因为此时union foo
的大小还不知道。
是否有一种技巧可以让我“填充”#34;与char数组的联合?
答案 0 :(得分:2)
嗯,有:
union bar {
union foo {
int a;
wchar_t b;
bar *c;
baz d;
} f;
char z[sizeof(union foo)];
};
得到正确的大小,但是在访问其他成员时你必须坚持f.
。
AFAIK如果没有f
,就无法做到这一点。但是,正如user1969104所暗示的那样,对您的问题可能有更好的解决方案。
这是一个丑陋的黑客:
#define UNION_FOO_Z(u) ( *(unsigned char (*)[sizeof(union foo)])&u )
用法:
union foo f;
printf("%zu\n", sizeof UNION_FOO_Z(f));
这种黑客可能存在对齐问题(虽然不太可能)。
答案 1 :(得分:1)
首先,使用除数组之外的所有内容声明一个联合,
union foo_almost {
int a;
wchar_t b;
bar *c;
baz d;
};
然后用一切声明联盟,
union foo {
int a;
wchar_t b;
bar *c;
baz d;
char z[sizeof(union foo_almost)];
};
有些人使用宏来执行此操作 - 将第一部分声明为FOO_ALMOST,但他们真正保存的只是输入,
#def FOO_ALMOST \
int a; \
wchar_t b; \
bar *c; \
baz d;
union foo_almost {
FOO_ALMOST
};
然后,
union foo {
FOO_ALMOST
char z[sizeof(union foo_almost)];
};
现在,sizeof(union foo_almost)和sizeof(union foo)应该是相同的。但是,您的编译器仍然可以分配比union foo类型的对象更多的内存。
不需要丑陋的黑客,除非你认为附加类型的联盟foo_almost是丑陋的。
注意,
union foo_almost fa;
union foo f;
printf("%zu\n", sizeof(fa));
printf("%zu\n", sizeof(f));