8

这个问题可以开始相信工会的联盟不小于其个人成员的最大联盟。但我对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));
};

这将产生以下输出:

sizeof(long long): 8
__alignof__(long long): 8
sizeof(ull): 8
__alignof__(ull): 4
sizeof(sll): 8
__alignof__(sll): 4

为什么工会成员的对齐比包含工会的大?

[更新]

根据基思的回答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。对于本地范围,我无法对此进行测试,因为编译器似乎可以自由地重新排列本地数据 - 所以这个技巧不起作用。你能对此发表评论吗?

[/更新]

4

1 回答 1

7

__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)))

这会产生由 a和 at组成的结构中类型成员的偏移量。使用这个宏,这个程序:chart

#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 字节对齐,并且包含 a 的结构或联合long long具有 4 字节对齐。

我怀疑这是 gcc 的__alignof__. 但是定义的模糊性使得很难确定它真的是一个错误。好像没有报道

更新 :

我可能会抢先一步,但我刚刚提交了一份错误报告

这个早期的错误报告,关闭为“INVALID”,与此类似,但它不涉及结构本身的对齐方式。

更新 2:

我的错误报告已作为先前报告的副本关闭。我会要求澄清。

于 2012-08-06T09:10:03.040 回答