我的非常简单的代码如下所示
#include <iostream>
#include <stdalign.h>
int main() {
char array_char[2] = {'a', 'b'};
float array_float[2] = {1, 2};
std::cout << "alignof(array_char): " << alignof(array_char) << std::endl;
std::cout << "alignof(array_float): " << alignof(array_float) << std::endl;
std::cout << "address of array_char: " << (void *) array_char << std::endl;
std::cout << "address of array_float: " << array_float << std::endl;
}
此代码的输出是
alignof(array_char):1
alignof(array_float):4
array_char的地址:0x7fff5e8ec580
array_float的地址:0x7fff5e8ec570
alignof
运算符的结果符合预期,但是两个数组的实际地址与它们不一致。无论我尝试了多少次,地址始终都是16个字节对齐。
我正在具有Intel CORE i5第七代CPU的Ubuntu 16.04上使用gcc 5.4.0。
我已经找到this补丁。
这似乎是GCC 6.4中修复的x86_64错误。
System V x86-64 ABI要求聚合类型(例如数组和struct
)必须至少对齐16个字节(如果它们的大小至少为16个字节)。根据ABI规范中的注释,这旨在促进SSE指令的使用。
[GCC似乎错误地将该规则应用于大小为16位(而不是字节)或更大的聚合。
我建议您将编译器升级到最新的GCC版本。
但是,这只是一个优化问题,而不是正确性问题。对变量进行更严格的对齐并没有什么错,并且(与上述SSE一样)在某些情况下过度对齐可能会带来性能上的好处,从而超过了浪费的堆栈内存的成本。