Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do C++ classes without member variables occupy space?

I found that both MSVC and GCC compilers allocate at least one byte per each class instance even if the class is a predicate with no member variables (or with just static member variables). The following code illustrates the point.

#include <iostream>  class A { public:    bool operator()(int x) const    {       return x>0;    } };  class B { public:    static int v;    static bool check(int x)    {       return x>0;    } };  int B::v = 0;  void test() {    A a;    B b;    std::cout << "sizeof(A)=" << sizeof(A) << "\n"              << "sizeof(a)=" << sizeof(a) << "\n"              << "sizeof(B)=" << sizeof(B) << "\n"              << "sizeof(b)=" << sizeof(b) << "\n"; }  int main() {    test();    return 0; } 

Output:

sizeof(A)=1 sizeof(a)=1 sizeof(B)=1 sizeof(b)=1 

My question is why does compiler need it? The only reason that I can come up with is ensure that all member var pointers differ so we can distinguish between two members of type A or B by comparing pointers to them. But the cost of this is quite severe when dealing with small-size containers. Considering possible data alignment, we can get up to 16 bytes per class without vars (?!). Suppose we have a custom container that will typically hold a few int values. Then consider an array of such containers (with about 1000000 members). The overhead will be 16*1000000! A typical case where it can happen is a container class with a comparison predicate stored in a member variable. Also, considering that a class instance should always occupy some space, what type of overhead should be expected when calling A()(value) ?

like image 944
bkxp Avatar asked Sep 11 '14 11:09

bkxp


People also ask

Why class does not consume any space?

A class definition is only used by the compiler as a blueprint for objects of that class. Once the program is compiled the class definition itself doesn't exist in the final executable, only the objects created for the class. Class methods do take space, exactly as free functions.

Can a class have no data members?

No, because static functions can't be declared as members of parent classes, while data-less member classes can. Thus the constructor of a member-less class in an enclosing class will be called automatically. This feature can'be reached by a static function.

Does class definition occupy memory?

Class does not occupy space in memory.

Why is the size of an empty class 1 byte?

Why actually an empty class in C++ takes one byte? Simply a class without an object requires no space allocated to it. The space is allocated when the class is instantiated, so 1 byte is allocated by the compiler to an object of an empty class for its unique address identification.


2 Answers

It’s necessary to satisfy an invariant from the C++ standard: every C++ object of the same type needs to have a unique address to be identifiable.

If objects took up no space, then items in an array would share the same address.

like image 157
Konrad Rudolph Avatar answered Sep 22 '22 02:09

Konrad Rudolph


Basically, it's an interplay between two requirements:

  • Two different objects of the same type must be at a different addresses.
  • In arrays, there may not be any padding between objects.

Note that the first condition alone does not require non-zero size: Given

struct empty {}; struct foo { empty a, b; }; 

the the first requirement could easily be met by having a zero-size a followed by a single padding byte to enforce a different address, followed by a zero-size b. However, given

empty array[2]; 

that no longer works because a padding between the different objects empty[0] and empty[1] would not be allowed.

like image 25
celtschk Avatar answered Sep 24 '22 02:09

celtschk