1

I have a class that goes like this:

class myType
{

  union {
      float data[4];
      other_vector4_type v
  } ;
  typedef union {
      float data[4];
      other_vector4_type v
  } myType-internal_t;

 <various member functions, operator overloads>

}

Now I want to use this type in my vertex buffer, but the sizeof() isn't as expected. I aligned the class to 16 bytes.

sizeof(myType) yields 64.

sizeof(myType::myType-internal_t) yields 32.

I've read quite a few articles on data alignment but I don't know where I'm using extra data. I tried stripping out the custom constructor but it remains the same, swapping the class keyword for struct doesn't change it either (I don't understand what it's for, as it happens!)

This is annoying, I'll use the internal type for now since I won't be touching the data often, but it would be great to have the class work like I want.

timrau
  • 22,578
  • 4
  • 51
  • 64
Sorlaize
  • 21
  • 2
  • 2
    Tell us what other_vector_type looks like. – bmargulies Nov 17 '09 at 15:04
  • 1
    You should made the code portion of your question more clear... – Pablo Santa Cruz Nov 17 '09 at 15:05
  • 2
    A complete test case (that compiles and uses correct syntax) would help get to the real issue. –  Nov 17 '09 at 15:06
  • 2
    `myType-internal_t` looks like a pretty fishy name to me. Are `-`'s even allowed in names? Looks to me like it'd be parsed as different identifiers, separated by a minus operator (although not sure how that'd even compile) – jalf Nov 17 '09 at 15:13
  • 1
    Without telling us anything about this mysterious `other_vector4_type`, you're not going to get a well-informed answer. But so far, earlz's answer is probably the best: the compiler gives you no guarantees regarding struct size. It is allowed to add in padding wherever it sees fit. – Charles Salvia Nov 17 '09 at 15:16
  • A compilable piece of code would be a minimum requirement. – Martin York Nov 17 '09 at 16:52

4 Answers4

2

A C++ compiler can make that struct 128 bytes for all it cares. The size of structs/unions is not defined by the C++ standard. However, most compilers have a nonstandard __PACKED attribute you can add to the declaration of a struct and it will take up only the exact amount of bytes that it needs

Earlz
  • 62,085
  • 98
  • 303
  • 499
  • There will usually by a cost associated with packing. There is a reason you need to explicitly add the attribute. So you should only use it if there is some reason you need to remove all the padding (ie align it with some internal kernel structure, or a packet for on the wire transport). – Martin York Nov 17 '09 at 16:49
1

If you have virtual functions in your class it will make your objects bigger than the internal type because of the vtable pointer.

BTW "struct { " is just the same as saying "class { public : "

siukurnin
  • 2,862
  • 17
  • 20
1

I imagine you will have a vtable pointer defined for your objects. Either because you have RTTI enabled or any virtual method (including the destructor) will add a vtable

http://en.wikipedia.org/wiki/Virtual_method_table

Typically, the compiler creates a separate vtable for each class. When an object is created, a pointer to this vtable, called the virtual table pointer or vpointer, is added as a hidden member of this object (becoming its first member unless it's made the last[2]). The compiler also generates "hidden" code in the constructor of each class to initialize the vpointers of its objects to the address of the corresponding vtable.

epatel
  • 45,805
  • 17
  • 110
  • 144
1

I just compiled

#include <xmmintrin.h>
#include <iostream>

struct myType
{
    union {
        float data[4];
        __v4sf v;
    };
    typedef union {
        float data[4];
        __v4sf v;
    } myType_internal_t;
};

int main() {
    std::cout << sizeof(myType) << std::endl;
    std::cout << sizeof(myType::myType_internal_t) << std::endl;
}

And the result is:

16
16

using gcc on a 64 bit arch. As expected. "__v4sf" is a vector type consisting of four floats. So the problem is probably in your "other_vector_4_type". Maybe it is polymorphic and virtual and contains two vtables? And you are using more virtual functions in "myType" which increase its size further? The problem may be related to your compiler or the architecture too.

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103