3 c++ x86 padding clang memory-alignment
我在 cpp.sh 上进行了一个实验(没有特殊标志),其中字大小似乎是 4 个字节。在我的实验中,我在堆栈上初始化了两个 type 元素Data,一个只有一个字符的结构,并打印出它们的地址。我对两个 char 类型的变量做了同样的事情。
#include <iostream>
#include <bitset>
struct Data {
char c;
};
void PrintAddr(const void* ptr) {
std::cout << std::bitset<32>((unsigned int) ptr) << std::endl;
}
int main()
{
std::cout << "word size = " << sizeof(size_t) << std::endl;
std::cout << "sizeof = " << sizeof(Data) << std::endl;
std::cout << "alignof = " << alignof(Data) << std::endl;
std::cout << "Data addresses: " << std::endl;
Data a, b;
PrintAddr(&a);
PrintAddr(&b);
std::cout << "char addresses: " << std::endl;
char c, d;
PrintAddr(&c);
PrintAddr(&d);
}
Run Code Online (Sandbox Code Playgroud)
输出:
word size = 4
sizeof = 1
alignof = 1
Data addresses:
00000000010100000101001011101000
00000000010100000101001011100000
char addresses:
00000000010100000101001011011111
00000000010100000101001011011110
Run Code Online (Sandbox Code Playgroud)
似乎为 Data 类型的变量 a 和 b 添加了填充,而没有为类型 c 和 d 添加了填充。为什么会这样呢?
迂腐的答案可能是 C++ 语言规范不保证局部变量的地址可能是什么。它们可能彼此相邻,或者可能有填充,或者它们可能完全不相关!语言律师可能会乐意就此打住。
如果您问为什么特定编译器会这样做,您可以修改您的问题(或添加标签)来指定这一点。
请注意,在您实际获取这些自动变量的地址之前,这些自动变量可能甚至没有地址 - 它们只是存在于寄存器中。对于变量来说可能更是如此char。
所以这就是我的猜测 - 您使用的编译器很乐意将自动char变量打包到堆栈上(当您获取它们的地址时),但不愿意以struct同样的方式打包自动变量。