Why Class Size Depend Only on Data Members and Not on Member Functions

Why class size depend only on data members and not on member functions?

Because the class's functions are not saved inside the object itself. Think of it in terms of C programming, every function of class A takes one secret parameter, the this pointer, so in actuality they are just functions with one extra parameter.

For example imagine it like this:

int display(A* thisptr)
{
//do something
printf("%d",thisptr->a);
return;
}

So the display function is saved as just a simple function with one extra parameter. The name though is mangled depending on the compiler.

I believe that different rules apply for virtual functions which would involve function pointers but since I am not sure maybe someone else can enlighten us on this matter.

c++ member function and class size

Member variables are stored as part of each class instance. But member functions are not.

Each instance of a class must have a separate copy of each member variable. This keeps each object unique.

But member functions are code. And no matter how many instances you have of a particular class, there is absolutely no reason to have multiple copies of the code. The same code simply operates on the instance data.

Since code is different, code is not part of the size of a class instance. And sizeof(myClass) will not include bytes occupied by code.

Why does the size of a class depends on the order of the member declaration? and How?

The reason behind above behavior is data structure alignment and padding. Basically if you are creating a 4 byte variable e.g. int, it will be aligned to a four byte boundary i.e. it will start from an address in memory, which is multiple of 4. Same applies to other data types. 2 byte short should start from even memory address and so on.

Hence if you have a 1 byte character declared before the int (assume 4 byte here), there will be 3 free bytes left in between. The common term used for them is 'padded'.

Data structure alignment

Another good pictorial explanation

Reason for alignment

Padding allows faster memory access i.e. for cpu, accessing memory areas that are aligned is faster e.g. reading a 4 byte aligned integer might take a single read call where as if an integer is located at a non aligned address range (say address 0x0002 - 0x0006), then it would take two memory reads to get this integer.

One way to force compiler to avoid alignment is (specific to gcc/g++) to use keyword 'packed' with the structure attribute. packed keyword Also the link specifies how to enforce alignment by a specific boundary of your choice (2, 4, 8 etc.) using the aligned keyword.

Best practice

It is always a good idea to structure your class/struct in a way that variables are already aligned with minimum padding. This reduces the size of the class overall plus it reduces the amount of work done by the compiler i.e. no rearrangement of structure. Also one should always access member variables by their names in the code, rather than trying to read a specific byte from structure assuming a value would be located at that byte.

Another useful SO question on performance advantage of alignment

For the sake of completion, following would still have a size of 8 bytes in your scenario (32 bit machine), but it won't get any better since full 8 bytes are now occupied, and there is no padding.

class temp
{
public:
int i;
short s;
char c;
char c2;
};

Why is a class' size affected when it contains only a virtual function?

Whenever a class contains at least one virtual function, the compiler needs to add RunTime Type Information to each of the objects. The implementation will usually add a single pointer to each object that refers to a structure, defined by the compiler and hidden from users, with a pointer to the type_info object and the vtable used for dynamic dispatch of functions.

In the case of a class with no non-static data members and at least one virtual function, the size of each object is the size of the per-object RTTI information (one pointer), and because that is non-zero, the compiler will not add extra space. What the quote is saying is that sizeof(T) != 0 for any and all types T, and a type with a dynamic function trivially fits that requirement. Only with types that would have zero size, the compiler is forced to make the object 1 char big.

Why doesn't sizeof care about functions?

What things are included in sizeof, and what things are not?

sizeof() only includes things that have to be stored in memory as part of each instance of the type. (For a class or structure, it returns the amount of memory that needs to be allocated for an instance.)

Since the function is the same for every instance of struct y, it's not stored as part of the structure -- defining it there just allows the function to be called as a method on the structure. If it were a function pointer, though, the pointer would be part of the structure, and would contribute to its size.

Memory allocation for member functions in C++

For each instance of the class, memory is allocated to only its member variables i.e. each instance of the class doesn't get it's own copy of the member function. All instances share the same member function code. You can imagine it as compiler passing a hidden this pointer for each member function so that it operates on the correct object. In your case, since C++ standard explictly prohibits 0 sized objects, class A and class B have the minimum possible size of 1. In case of class C since there is a virtual function each instance of the class C will have a pointer to its v-table (this is compiler specific though). So the sizeof this class will be sizeof(pointer).



Related Topics



Leave a reply



Submit