1

In a project with old code I'm having to deal with, I have this Coord structure. As best as I can tell it's size should be either 12 bytes, or 24. However, sizeof(Coord returns 40. Could someone please explain where this extra size comes from?

struct Coord
{
    Coord();
    float inate[3] = {0,0,0};
    float& x = inate[0];
    float& y = inate[1];
    float& z = inate[2];
    Coord operator*(const float&);
    Coord operator=(const Coord&);
    Coord operator=(const float[3]);
    Coord dot(const Coord& c);
    Coord cross(const Coord& c);
};
Greg S.
  • 48
  • 8
  • Look into padding – Kevin May 05 '18 at 00:45
  • I'm sure this is a duplicate. – Keith Thompson May 05 '18 at 00:47
  • The compiler cannot optimize away your reference class members, because the compiler cannot prove how your explicitly declared default constructor initializes them. As such, each reference must be implemented as a pointer. You must be a using a 64 bit platform, where sizeof pointer is 8 bytes. 4*3 + 8 * 3 = 36. The compiler must've decided to add 4 bytes worth of padding in the internal layout of this class, between the floats and the pointers, so that the pointers align on an 8 byte boundary. 40 bytes. Q.E.D. – Sam Varshavchik May 05 '18 at 00:56
  • I get 24 with VS2017 32 bit build. I get 40 with VS2017 64 bit build. – ttemple May 05 '18 at 01:03
  • if you replace each "float& " attribute with the float& function, i.e. "float& x() { return inate[0]; }", (on ubuntu 17.10 64 bit) the sizeof(Coord) changes from 40 to 12. Methods contribute nothing to the struct size. – 2785528 May 05 '18 at 01:42

2 Answers2

2

The size of pointers/references on your machine is probably 8 bytes. So Coord uses 12 bytes for float array and 24 bytes for the three references, so the struct itself takes 36 bytes. The remaining 4 bytes is due to padding to align the pointers on word boundary.

How to define an equivalent struct without incurring pointer cost? You can use union:

struct Coord
{
    union {
        float inate[3] = {0,0,0};
        float x, y, z;
    };
};

sizeof is 12 for this version of Coord.

Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
1

The references are pointers. Depending of the memory model (32-bits, 64-bits), the references will need 4 bytes or 8 bytes. A 64 bit model, will align the data on 8 bytes boundaries, that means 4 bytes padding between inate[2] and the reference x.

So that, for 32 bits you get 4 bytes x 3 + 4 bytes x 3 = 24 bytes; in a 64 bits model you get 4 bytes x 3 + 4 bytes for padding + 8 bytes x 3 = 12 + 4 + 24 = 40 bytes.