0
#include <iostream>

class B
{
    public:
    virtual void f() {std::cout<<"HI";}
    int x;
};
class A
{
    public:
    void f() {std::cout<<"HI";}
    int x;
};

int main () {
  A a;
  B b;
  std::cout<<sizeof(a)<<" "<<sizeof(b);

  return 0;
}

The output is

4 16 

I expected it to be 8 bytes longer - vptr pointer. But for what the rest 4 bytes is used? I found quite many forum posts (all from some years ago) where people discussed that object from the class with vprt is 4 or 8 bytes longer. I checked also on online C++ shell - output there is the same.

SimpleAsk
  • 73
  • 5
  • 8
    Alignment padding, I'm guessing. – Fred Larson May 21 '20 at 20:50
  • 3
    See my answer here: https://stackoverflow.com/questions/58435348/what-is-bit-padding-or-padding-bits-exactly/58436082#58436082 Not sure if it qualifies as a dupe or not. – NathanOliver May 21 '20 at 20:51
  • 1
    It's because of a new pointer to virtual functions table and of course padding, (from 12 to the nearest perfect power of two, which is 16). Check this [answer](https://stackoverflow.com/questions/9439240/sizeof-class-with-int-function-virtual-function-in-c) on a similar question. – sanitizedUser May 21 '20 at 20:53
  • @FredLarson oh, you saved my time, thanks a lot! I completely forget that alignment can occur. With long int it's 8 and 16 – SimpleAsk May 21 '20 at 20:54
  • If you compiled for a 32-bit target, instead of 64-bit, you would observe different sizes. Namely, _4_ and _8_. – Ron May 21 '20 at 21:29
  • Compiler and arch dependent. For Q like that, you should at least always specify exact compiler and arch used for tests; and probably also print `sizeof` fundamental types used (a `void*` at least). – curiousguy Jun 30 '20 at 13:24

1 Answers1

3

It seems that the pointer to the table of pointers to virtual functions has a size of 8 bytes. So the class B is aligned to the boundary of 8 bytes that is it has 4 additional padding bytes.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335