By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,244 Members | 1,100 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,244 IT Pros & Developers. It's quick & easy.

I'm confused about the space a class takes in a structure?

P: n/a
Pep
I'm getting weird results at the moment so thought I'd rebase my
knowledge of c++ storage with your help :)

I have a class used as a type in a struct and the struct is handled by
a 3rd party binary writed for persistent storage. I am confused by the
results I am getting and am not sure how the 3rd party writer is
seeing the size of the stuct.

class foo
// I have not included the methods for brevity
{
public:
unsigned short shortArray[4];
};

typedef struct
{
foo fooVar;
char charArray[8];
} bar;

So if you do a sizeof(foo) you get back 8 as a result and a
sizeof(bar) returns 16. However the class foo has methods as well. Now
if I was to do any form of binary copy on bar such as using memcpy for
example using the sizeof(bar) as the length, will I definitely be
copying the complete data in bar or will the operation be thrown out
by things like internal members in foo created by the compiler, like
the vtbl in foo?

TIA :)

Aug 17 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Pep wrote:
I'm getting weird results at the moment so thought I'd rebase my
knowledge of c++ storage with your help :)

I have a class used as a type in a struct and the struct is handled by
a 3rd party binary writed for persistent storage. I am confused by the
results I am getting and am not sure how the 3rd party writer is
seeing the size of the stuct.

class foo
// I have not included the methods for brevity
{
public:
unsigned short shortArray[4];
};
It makes a difference what kind of "methods" this class has. If it
doesn't have user-defined constructors, or virtual functions, it's
most likely a POD class, which means it's safe to use 'memcpy' on it.
typedef struct
{
foo fooVar;
char charArray[8];
} bar;
Tell us, why do you do the wicked typedef dance here? Why don't you
simply write

struct bar
{
foo fooVar;
char charArray[8];
};

?
>
So if you do a sizeof(foo) you get back 8 as a result
OK, so your 'short' is 2 bytes long, most likely.
and a
sizeof(bar) returns 16.
It seems that the compiler adds no padding in the 'bar' objects.
However the class foo has methods as well.
Again, depends on what methods those are.
Now
if I was to do any form of binary copy on bar such as using memcpy for
example using the sizeof(bar) as the length, will I definitely be
copying the complete data in bar or will the operation be thrown out
by things like internal members in foo created by the compiler, like
the vtbl in foo?
If sizeof(foo) == sizeof(short[4]), there are no "internal members"
with which you need to concern yourself.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 17 '07 #2

P: n/a
Pep wrote:
So if you do a sizeof(foo) you get back 8 as a result and a
sizeof(bar) returns 16. However the class foo has methods as well. Now
if I was to do any form of binary copy on bar such as using memcpy for
example using the sizeof(bar) as the length, will I definitely be
copying the complete data in bar or will the operation be thrown out
by things like internal members in foo created by the compiler, like
the vtbl in foo?
How can foo have a virtual table when it has no virtual methods?
If it had a virtual table you would see it in the size of foo:
Instead of being 8 (ie. 4 2-byte shorts) it would probably be
12 (or 16 if you are compiling in a 64-bit system). That's because
a class with virtual methods has (in most compiler implementations)
a pointer to the virtual table inside it.

Even if it had virtual methods, it doesn't really matter. The pointer
to the virtual table will be the same for all objects of the same type.
Thus if you copy an object of type foo to an object of type foo, the
virtual table pointer will be the same.

Exactly what kind of incomplete data would you expect memcpy() to copy
in this case?
Of course you should take into account that memcpy() skips
constructors, copy constructors and assignment operators. Assuming you
don't have any of those, I suppose it doesn't matter.
Aug 17 '07 #3

P: n/a
Pep

Juha Nieminen wrote:
Pep wrote:
So if you do a sizeof(foo) you get back 8 as a result and a
sizeof(bar) returns 16. However the class foo has methods as well. Now
if I was to do any form of binary copy on bar such as using memcpy for
example using the sizeof(bar) as the length, will I definitely be
copying the complete data in bar or will the operation be thrown out
by things like internal members in foo created by the compiler, like
the vtbl in foo?

How can foo have a virtual table when it has no virtual methods?
If it had a virtual table you would see it in the size of foo:
Instead of being 8 (ie. 4 2-byte shorts) it would probably be
12 (or 16 if you are compiling in a 64-bit system). That's because
a class with virtual methods has (in most compiler implementations)
a pointer to the virtual table inside it.
Yep, it was more a badly worded question as to "what should I look out
for" to refresh my memory as usually I no longer have to worry about
the sort of things any more.
Even if it had virtual methods, it doesn't really matter. The pointer
to the virtual table will be the same for all objects of the same type.
Thus if you copy an object of type foo to an object of type foo, the
virtual table pointer will be the same.

Exactly what kind of incomplete data would you expect memcpy() to copy
in this case?
Of course you should take into account that memcpy() skips
constructors, copy constructors and assignment operators. Assuming you
don't have any of those, I suppose it doesn't matter.
Yep, I don;t really know if they are using memcpy in the database code
or not as they are very cagey when we talk to them about their
product. All I do know is that they are definitely doing binary copy
(of some form) on the data we send which they expect to be a struct
type.

So basically from what I can glean from everyones answers is that I
can rely on the result of the sizeof() off the struct against my
knowledge of the sizeof the sum of the scalars in the struct and the
class. As long as those are the same then I should have no problems.

Cheers.

Aug 17 '07 #4

P: n/a
On Aug 17, 8:33 am, Pep <pepaltavi...@yahoo.co.ukwrote:
Juha Nieminen wrote:
Pep wrote:
So if you do a sizeof(foo) you get back 8 as a result and a
sizeof(bar) returns 16. However the class foo has methods as well. Now
if I was to do any form of binary copy on bar such as using memcpy for
example using the sizeof(bar) as the length, will I definitely be
copying the complete data in bar or will the operation be thrown out
by things like internal members in foo created by the compiler, like
the vtbl in foo?
How can foo have a virtual table when it has no virtual methods?
If it had a virtual table you would see it in the size of foo:
Instead of being 8 (ie. 4 2-byte shorts) it would probably be
12 (or 16 if you are compiling in a 64-bit system). That's because
a class with virtual methods has (in most compiler implementations)
a pointer to the virtual table inside it.

Yep, it was more a badly worded question as to "what should I look out
for" to refresh my memory as usually I no longer have to worry about
the sort of things any more.
Even if it had virtual methods, it doesn't really matter. The pointer
to the virtual table will be the same for all objects of the same type.
Thus if you copy an object of type foo to an object of type foo, the
virtual table pointer will be the same.
Exactly what kind of incomplete data would you expect memcpy() to copy
in this case?
Of course you should take into account that memcpy() skips
constructors, copy constructors and assignment operators. Assuming you
don't have any of those, I suppose it doesn't matter.

Yep, I don;t really know if they are using memcpy in the database code
or not as they are very cagey when we talk to them about their
product. All I do know is that they are definitely doing binary copy
(of some form) on the data we send which they expect to be a struct
type.
In that case, your best bet may be to create a POD type that mirrors
your class, copy into the POD, and forward to the database class for
serialization.

Alternatively, if you can rewrite some of your code....

struct PODdata
{
// all the POD data to be serialized goes here
};

class Myclass : private PODdata // note private inheritance
{
// methods, constructors, etc....
public:
PODdata* as_PODdata() { return this; }
};

And pass the result of as_PODdata() to your serializer.
Aug 17 '07 #5

P: n/a
>
So basically from what I can glean from everyones answers is that I
can rely on the result of the sizeof() off the struct against my
knowledge of the sizeof the sum of the scalars in the struct and the
class. As long as those are the same then I should have no problems.

Cheers.
size of the struct may be greater than the sum of the sizes of its
members due to alignment issues unless your compiler align them at
byte
boundaries which it doesn't if you haven't specifically said so.

Aug 17 '07 #6

P: n/a
hurcan solter wrote:
size of the struct may be greater than the sum of the sizes of its
members due to alignment issues unless your compiler align them at
byte
boundaries which it doesn't if you haven't specifically said so.
Note that one cannot assume that elements in structs/classes can be
packed at byte boundaries in all architectures. There exist
architectures (such as the Sun UltraSparc) where it's just not possible
to store multiple-byte elements at anything else than at word bounaries
(trying to access a multiple-byte element not at word boundary will
cause a bus error interrupt).
Aug 18 '07 #7

P: n/a

"Juha Nieminen" <no****@thanks.invalidwrote in message
news:46**********************@news.song.fi...
hurcan solter wrote:
> size of the struct may be greater than the sum of the sizes of its
members due to alignment issues unless your compiler align them at
byte
boundaries which it doesn't if you haven't specifically said so.

Note that one cannot assume that elements in structs/classes can be
packed at byte boundaries in all architectures.
Which may not be a problem if the program runs on the platform without
communicating to another platform: "fix it up" at he boundary to match up
with the characteristics of the platform that was chosen to represent the
protocol.

John

Aug 18 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.