英文:
Why is alignment on the stack for a struct with 1 member (char) handled differently than if the member was directly on the stack?
问题
我在cpp.sh上运行了一个实验(没有特殊标志),其中字长似乎为4字节。在实验中,我在堆栈上初始化了两个类型为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);
}
输出:
word size = 4
sizeof = 1
alignof = 1
Data addresses:
00000000010100000101001011101000
00000000010100000101001011100000
char addresses:
00000000010100000101001011011111
00000000010100000101001011011110
似乎对于类型为Data的变量a和b添加了填充,而对于类型为c和d的变量没有添加任何填充。为什么会这样呢?
英文:
I ran an experiment on cpp.sh (no special flags) where the word size seems to be 4 bytes. In my experiment, I initialized two elements of type Data
, a struct with just a single char, on the stack and printed out their addresses. I did the same with two variables of type 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);
}
Output:
word size = 4
sizeof = 1
alignof = 1
Data addresses:
00000000010100000101001011101000
00000000010100000101001011100000
char addresses:
00000000010100000101001011011111
00000000010100000101001011011110
It seems like padding is being added for variables a and b, of type Data, while there is none being added for type c and d. Why is this the case?
答案1
得分: 5
A pedantic answer might be that the C++ language specification gives no guarantees of what the addresses of local variables might be. They might be next to each other, or there might be padding, or they might be completely unrelated! A language-lawyer might be happy to leave it at that.
If you're asking why a specific compiler does that, you could amend your question (or add tags) to specify that.
Note that these automatic variables probably wouldn't even have addresses until you actually take their address - they'd just live in registers. Probably more so for the char
variables.
So that's my guess - the compiler you use is happy to pack automatic char
variables on the stack (when you take their addresses), but is reluctant to pack automatic struct
variables the same way.
英文:
A pedantic answer might be that the C++ language specification gives no guarantees of what the addresses of local variables might be. They might be next to each other, or there might be padding, or they might be completely unrelated! A language-lawyer might be happy to leave it at that.
If you're asking why a specific compiler does that, you could amend your question (or add tags) to specify that.
Note that these automatic variables probably wouldn't even have addresses until you actually take their address - they'd just live in registers. Probably more so for the char
variables.
So that's my guess - the compiler you use is happy to pack automatic char
variables on the stack (when you take their addresses), but is reluctant to pack automatic struct
variables the same way.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论