Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is alignment on the stack for a struct with 1 member (char) handled differently than if the member was directly on the stack?

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 Answers

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.

like image 104
pmacfarlane Avatar answered Dec 02 '25 06:12

pmacfarlane



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!