Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will sizeof always be the same?

Tags:

c++

sizeof

I have a quick question about class structuring, padding, and the resulting sizeof the class. In the below example, on every compiler I've tested, the result is always 40 bytes for sizeof A, which makes sense to me.

#include <iostream>
class A {
    int a, b; // 4 + 4
    short c;  // + 2
    double f; // not currently 8 byte aligned. Currently 10 bytes, so pad 6 extra bytes, so: + 6 + 8
    char w;   // + 1
    bool d;   // + 1
    double g; // not currently 8 byte aligned. Currently 26 bytes, so pad 6 extra bytes, so: + 6 + 8

    // 4 + 4 + 2 + 6 + 8 + 1 + 1 + 6 + 8 = 40
};

int main() {
    std::cout << sizeof( A );
}

My question is, will this always be true? (assume the alignof and sizeof each individual member doesn't change). I know I can reorder it, so that the doubles come first, and it shrinks down to 32 bytes; but can a compiler make this decision? Or is it the always the programmer's responsibility? (I'm assuming the compiler can't reorder)

like image 383
ChrisMM Avatar asked Dec 13 '19 15:12

ChrisMM


People also ask

Is sizeof always a multiple of Alignof?

So sizeof(T) must be a multiple of alignof(T) !

Is sizeof always in bytes?

sizeof always returns size as the number of bytes.

What is sizeof structure?

Size of the struct should be sum of all the data member, which is: Size of int n1+ size of int* n2 +size of char c1+ size of char* c2. Now considering the 64-bit system, Size of int is 4 Bytes. Size of character is 1 Byte. Size of any pointer type is 8 Bytes.

How is sizeof calculated?

The size of an instance of any class is at least 1 byte, even if the class is empty, so that different objects will have different addresses. Adding a char ensures that different objects will have different addresses, so the compiler doesn't artificially add one to the size. The size is then sizeof(char) = 1.


1 Answers

sizeof(A) in the execution of your program will always be the same. If you change the order of the members or how A is packed and recompile, then you can/will get a different value. If you compile with a different compiler the size can also change. It can also change on different machines using the same compiler because different machines can have different sizes for the fundamental types.

Long story short, if you depend on your class being a specific size then add a static_assert that checks for that. That way if it does change, you'll get a nice compiler error instead of possible UB.

I know I can reorder it, so that the doubles come first, and it shrinks down to 32 bytes; but can a compiler make this decision?

No, the compiler cannot reorder the members for better packing since your class is a standard layout class and all members must be laid out in memory in declared order.

like image 100
NathanOliver Avatar answered Nov 03 '22 00:11

NathanOliver