Pio*_*ycz 8 c++ g++ memory-alignment unsigned-long-long-int unions
从这个问题开始,人们可以开始相信联盟的一致性不低于其个体成员的最大一致性.但我对long longgcc/g ++中的类型有问题.完整的示例可以在这里找到,但这里是我的问题的相关部分:
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));
};
Run Code Online (Sandbox Code Playgroud)
这导致以下输出:
sizeof(long long): 8
__alignof__(long long): 8
sizeof(ull): 8
__alignof__(ull): 4
sizeof(sll): 8
__alignof__(sll): 4
Run Code Online (Sandbox Code Playgroud)
为什么union成员的对齐大于包含union的对齐?
[UPDATE]
根据基思的回答,对齐在这里是错误的.但我测试了以下内容,似乎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));
};
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
因此,全局数据中的对齐long long为8,并且包含的对齐long long为4.对于本地范围,我无法测试这个,因为似乎编译器可以自由重新排列本地数据 - 所以这个技巧不起作用.你能评论一下吗?
[/ UPDATE]
__alignof__(这是gcc扩展名)不一定报告类型所需的对齐方式.
例如,对于任何类型,x86处理器实际上不需要超过1字节的对齐.如果对象是字对齐的,则访问4字节或8字节对象可能会更有效,但字节对齐就足够了.
引用gcc文档:
有些机器实际上从不需要对齐; 即使在奇数地址,它们也允许引用任何数据类型.对于这些机器,
__alignof__报告GCC将给出数据类型的最小对齐,通常由目标ABI强制执行.
但这仍然没有真正回答这个问题.即使有这个松散的定义,我也没有想到任何有理由__alignof__表明long long比包含a的结构或联合更严格的对齐long long.
确定类型对齐的更便携方法是:
#define ALIGNOF(type) ((int)(offsetof(struct {char c; type t;}, t)))
Run Code Online (Sandbox Code Playgroud)
这会产生t由a char和a 组成的结构中类型成员的偏移量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));
};
Run Code Online (Sandbox Code Playgroud)
在我的系统上生成此输出(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
Run Code Online (Sandbox Code Playgroud)
我的ALIGNOF()宏指示的结果是一致的:long long具有4字节对齐,以及包含long long4字节对齐的结构或联合.
我怀疑这是一个bug,或者至少是一个不一致的,在gcc的实现中__alignof__.但是定义的模糊性使得很难确定它真的是一个错误.似乎没有报道.
更新:
我可能会开枪,但我刚刚提交了一份错误报告.
这个早期的错误报告,关闭为"INVALID",类似,但它并不是指结构本身的对齐方式.
更新2:
我的错误报告已作为早期错误报告的副本关闭.我会要求澄清.
| 归档时间: |
|
| 查看次数: |
1249 次 |
| 最近记录: |