class align vs struct align
-
Hello to everyone (as this is my first question here) I'm trying to understand how class members aligned (with msvc compiler). I was expecting that this would be identical with a struct. And it is as long as the class doesn't contain virtual methods. But when it does sometimes are equal sometimes not. For example
struct s {
unsigned* p;
int n;
double d;
};
//i get size 16, but for the class
class cc {
public:
virtual void msg() { cout<<"c::msg"<<endl; }
private:
int n;
double d;
};
//i get size 24thanks in advance
modified on Tuesday, August 12, 2008 6:03 PM
-
Hello to everyone (as this is my first question here) I'm trying to understand how class members aligned (with msvc compiler). I was expecting that this would be identical with a struct. And it is as long as the class doesn't contain virtual methods. But when it does sometimes are equal sometimes not. For example
struct s {
unsigned* p;
int n;
double d;
};
//i get size 16, but for the class
class cc {
public:
virtual void msg() { cout<<"c::msg"<<endl; }
private:
int n;
double d;
};
//i get size 24thanks in advance
modified on Tuesday, August 12, 2008 6:03 PM
That is probably because your allignment is set to 8. Try setting it to 4,and you should get sizes 8 and 12. :)
Bram van Kampen
-
That is probably because your allignment is set to 8. Try setting it to 4,and you should get sizes 8 and 12. :)
Bram van Kampen
Thanks for the quick response Bram. Unfortunately this is not my problem. So let me make it more clear. I have a class with a virtual method (or two or a hudrent, there is no difference), an integer and a double and a 32bit os. So i expect to get 4 bytes for the vptr, 4 bytes for the int, 8 for the double and no need for padding anywhere between, because they are already aligned. Exactly what i have in the struct (pointer, int, double). Why do i get different sizes and member alignment?
modified on Tuesday, August 12, 2008 6:03 PM
-
Thanks for the quick response Bram. Unfortunately this is not my problem. So let me make it more clear. I have a class with a virtual method (or two or a hudrent, there is no difference), an integer and a double and a 32bit os. So i expect to get 4 bytes for the vptr, 4 bytes for the int, 8 for the double and no need for padding anywhere between, because they are already aligned. Exactly what i have in the struct (pointer, int, double). Why do i get different sizes and member alignment?
modified on Tuesday, August 12, 2008 6:03 PM
Point Taken! X| Well, experimenting a bit, and checking offsetof(Struct,n) vs offsetof(Class,n), it appears that the compiler for it's own reason sets aside 8 bytes for the vtable pointer. For one thing, you can be sure that this is and will be always these 8 bytes. The Entire COM architecture relies on the proposition that a Class with a virtual function equals a vtable Pointer followed by a structure. The C interface and the CPP interface are both able to work with the same data. If this were to change, the entire COM machinery would break. :)
Bram van Kampen
-
Point Taken! X| Well, experimenting a bit, and checking offsetof(Struct,n) vs offsetof(Class,n), it appears that the compiler for it's own reason sets aside 8 bytes for the vtable pointer. For one thing, you can be sure that this is and will be always these 8 bytes. The Entire COM architecture relies on the proposition that a Class with a virtual function equals a vtable Pointer followed by a structure. The C interface and the CPP interface are both able to work with the same data. If this were to change, the entire COM machinery would break. :)
Bram van Kampen
-
Hello to everyone (as this is my first question here) I'm trying to understand how class members aligned (with msvc compiler). I was expecting that this would be identical with a struct. And it is as long as the class doesn't contain virtual methods. But when it does sometimes are equal sometimes not. For example
struct s {
unsigned* p;
int n;
double d;
};
//i get size 16, but for the class
class cc {
public:
virtual void msg() { cout<<"c::msg"<<endl; }
private:
int n;
double d;
};
//i get size 24thanks in advance
modified on Tuesday, August 12, 2008 6:03 PM
Its same for class and struct. For instance, Add a virtual function to
struct s
and you'll get thesizeof struct s
as 24.struct s {
// unsigned* p;
virtual void msg() { cout<<"c::msg"<<endl; }
int n;
double d;
};If you disable padding and check the size of
class cc
, you'll get 16 bytes for your class.// Disable padding.
#pragma pack(1)class cc {
public:
virtual void msg() { cout<<"c::msg"<<endl; }
private:
int n;
double d;
};The point is, if your class have vtable, for some reason, compiler is adding a 4 bytes padding between vtbl ptr and other member variables. If you disable padding, it will be removed. I'm not sure about the purpose. :doh: Well, I hope atleast my reply helped you to some extend. :-D Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
-
Its same for class and struct. For instance, Add a virtual function to
struct s
and you'll get thesizeof struct s
as 24.struct s {
// unsigned* p;
virtual void msg() { cout<<"c::msg"<<endl; }
int n;
double d;
};If you disable padding and check the size of
class cc
, you'll get 16 bytes for your class.// Disable padding.
#pragma pack(1)class cc {
public:
virtual void msg() { cout<<"c::msg"<<endl; }
private:
int n;
double d;
};The point is, if your class have vtable, for some reason, compiler is adding a 4 bytes padding between vtbl ptr and other member variables. If you disable padding, it will be removed. I'm not sure about the purpose. :doh: Well, I hope atleast my reply helped you to some extend. :-D Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
>>if your class have vtable, for some reason, compiler is adding a 4 bytes padding between vtbl ptr and other member variables Thanks for the reply Jijo. As I mentioned before, this doesn't seems to be a rule. If I have virtual methods and just an integer for data member, there is no padding. The size is 8 bytes. I'm working on a small tutorial about inheritance, virtual calls etc in c++. Alignment is not a subject here, but since I demonstrate datamember access via offsets from the base address, I just want a clue why this happens, not the complete explanation.
modified on Wednesday, August 13, 2008 8:11 AM
-
>>if your class have vtable, for some reason, compiler is adding a 4 bytes padding between vtbl ptr and other member variables Thanks for the reply Jijo. As I mentioned before, this doesn't seems to be a rule. If I have virtual methods and just an integer for data member, there is no padding. The size is 8 bytes. I'm working on a small tutorial about inheritance, virtual calls etc in c++. Alignment is not a subject here, but since I demonstrate datamember access via offsets from the base address, I just want a clue why this happens, not the complete explanation.
modified on Wednesday, August 13, 2008 8:11 AM
Hi, I've bookmarked this conversation. It merrits more investigation, particularly the effect of declaring a double. Sometimes MS has rules for their own reasons. My COM argument still stands I think. It may be a surrepticcious rule MS introduced to cover a previous bug. At least, it is unexpected behaviour. :)
Bram van Kampen