Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size of base class inside derived class

Tags:

c++

Suppose I have class with no data:

struct Empty {
  /*some methods here*/
};

And a derived class

struct Derived: Empty {
  int a;
  int b;
  char c;
  ....
}__attribute__((packed));`

Objects of Empty class have size = 1. Empty part of derived class usually has 0 size. As I understand compiler see that base Empty class has no data so it can optimize size of Empty in case it is "inside" Derived but it is not required to do it by the standard.

So the question is:

Can I somehow determine at compile time that Empty part of Derived class doesn't really occupy memory.

I understand that I can do check like sizeof(Derived) = sizeof(a) + sizeof(b) ... But It is too verbose and there are several classes like Derived. Is there more elegant solution?

like image 910
Seleznev Anton Avatar asked Jan 16 '17 09:01

Seleznev Anton


2 Answers

You can use std::is_empty to make sure that the class you're inheriting from is zero-sized:

static_assert(std::is_empty<Empty>{});

If it is, empty base optimization is guaranteed to take place for standard-layout classes.


I understand that I can do check like sizeof(Derived) = sizeof(a) + sizeof(b) ... But It is too verbose. Is there more elegant solution?

This does not work properly because you need to take padding into account and eventual attributes such as packed.

like image 105
Vittorio Romeo Avatar answered Oct 30 '22 09:10

Vittorio Romeo


You can use more "old" (before C++11) macro - offsetof:

struct Empty {};
struct NonEmpty {
  int a;
};
struct Derived1: Empty {
  int a;
  int b;
  char c;
};
struct Derived2: NonEmpty {
  int a;
  int b;
  char c;
};
static_assert(offsetof(Derived1,a) == 0,"");
static_assert(offsetof(Derived2,a) != 0,"");

You can use this macro to check order of your member variables too:

static_assert(offsetof(Derived,a) < offsetof(Derived,b),"");
static_assert(offsetof(Derived,b) < offsetof(Derived,c),"");

But do not forget - offsetof has the same limitation:

If type is not a standard layout type, the behavior is undefined. If member is a static member or a member function, the behavior is undefined.

like image 3
SergV Avatar answered Oct 30 '22 10:10

SergV