从this question开始,人们可以开始相信联盟的对齐不小于其个人成员的最大对齐。但我对gcc / g ++中的long long
类型有疑问。可以找到完整的示例here,但这里是我的问题的相关部分:
union ull {
long long m;
};
struct sll {
long long m;
};
int main() {
#define pr(v) cout << #v ": " << (v) << endl
pr(sizeof(long long));
pr(__alignof__(long long));
pr(sizeof(ull));
pr(__alignof__(ull));
pr(sizeof(sll));
pr(__alignof__(sll));
};
这导致以下输出:
sizeof(long long): 8
__alignof__(long long): 8
sizeof(ull): 8
__alignof__(ull): 4
sizeof(sll): 8
__alignof__(sll): 4
为什么union成员的对齐方式大于包含union的对齐方式?
[UPDATE]
根据基思的回答 alignof 在这里是错误的。但我测试了以下内容,似乎 alignof 告诉我们真实情况。参见:
union ull {
long long m;
};
long long a;
char b;
long long c;
char d;
ull e;
int main() {
#define pr(v) cout << #v ": " << (v) << endl
pr(size_t((void*)&b));
pr(size_t((void*)&c));
pr(size_t((void*)&d));
pr(size_t((void*)&e));
pr(size_t((void*)&c) - size_t((void*)&b));
pr(size_t((void*)&e) - size_t((void*)&d));
};
输出:
size_t((void*)&b): 134523840
size_t((void*)&c): 134523848
size_t((void*)&d): 134523856
size_t((void*)&e): 134523860
size_t((void*)&c) - size_t((void*)&b): 8
size_t((void*)&e) - size_t((void*)&d): 4
因此,long long
的对齐为8,并且包含long long
的联合对齐在全局数据中为4。对于本地范围,我无法测试这个,因为似乎编译器可以自由重新排列本地数据 - 所以这个技巧不起作用。你能对此发表评论吗?
[/ UPDATE]
答案 0 :(得分:7)
__alignof__
(这是gcc扩展名)不一定报告类型的必需对齐方式。
有些机器实际上从不需要对齐;他们允许参考 甚至在奇数地址的任何数据类型。对于这些机器,
__alignof__
报告了GCC给出的最小一致性 数据类型,通常由目标ABI强制执行。
但这仍然没有真正回答这个问题。即使有那么宽松的定义,我也没有想到__alignof__
指出long long
的更严格的对齐比包含long long
的结构或联合更好的理由。
确定类型对齐的更便携的方法是:
#define ALIGNOF(type) ((int)(offsetof(struct {char c; type t;}, t)))
这会在由t
和char
组成的结构中产生t
类型成员的偏移量。使用这个宏,这个程序:
#include <iostream>
#include <cstddef>
union ull {
long long m;
};
struct sll {
long long m;
};
#define ALIGNOF(type) ((int)(offsetof(struct {char c; type t;}, t)))
int main() {
#define pr(v) std::cout << #v ": " << (v) << std::endl
pr(sizeof(long long));
pr(__alignof__(long long));
pr(ALIGNOF(long long));
pr(sizeof(ull));
pr(__alignof__(ull));
pr(ALIGNOF(ull));
pr(sizeof(sll));
pr(__alignof__(sll));
pr(ALIGNOF(sll));
};
在我的系统上生成此输出(gcc-4.7,Ubuntu 12.04,x86):
sizeof(long long): 8
__alignof__(long long): 8
ALIGNOF(long long): 4
sizeof(ull): 8
__alignof__(ull): 4
ALIGNOF(ull): 4
sizeof(sll): 8
__alignof__(sll): 4
ALIGNOF(sll): 4
我的ALIGNOF()
宏指示的结果是一致的:long long
具有4字节对齐,包含long long
的结构或联合具有4字节对齐。
我怀疑在gcc的__alignof__
实现中这是一个错误,或者至少是一个不一致的错误。但是定义的模糊性使得很难确定它真的是一个错误。 It doesn't seem to have been reported
更新:
我可能会开枪,但我刚刚提交了bug report。
此earlier bug report,关闭为“INVALID”,类似,但它不是指结构本身的对齐方式。
更新2:
我的错误报告已作为前一个报告的副本关闭。我会要求澄清。