Ordering of class members in memory

Started by
14 comments, last by SirLuthor 18 years, 8 months ago
Hello once again good people! Here's the deal.. I'm messing around with some funky memory management, and, well, some of it relies on manually finding the members of a class in memory, instead of just obtaining a pointer to the class and using that. Now, I was curious, in an object with no virtual functions, do members appear in memory in exactly the same order as in the class definition, starting from where the object starts? That is to say, the this pointer would point to the first member? What about objects with virtual functions, or inheritance? It would be positively spiffing if someone could possibly explain this for me, or point out a web page that could. Or if it's undefined behaviour, well, that's an answer too. Thanks!
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
Advertisement
Yes, the are guaranteed to be in order and the first member will appear directly at the beginning of the a non-virtual structure, inheritance in itself does not affect anything.
However alignment and padding prevents the placement of member from being completely predictable.

You may also want to check out the offsetof macro in stddef.h and C++'s pointers to data members.
Ok, you're walking on dangerous ground here, but yes, as far as I know that's how members are stored(taking into consideration the aligning). Of course, if the object have ancestors, you have to account their members too. In classes with virtual functions, the first 4 bytes are used to store a pointer to the virtual function table, and then come the members.

-EDIT:

Quote:
...inheritance in itself does not affect anything.


Hmm, is that true? Where are the members of the ancestor stored then?

-EDIT2: Ok, I just checked it out, first come the members of the ancestor(s), in order of inheritance, then the members of the current class.
But if I'm specifically aligning my members to 32 bit boundaries (or 64, when applicable), I should have nothing to fear from padding and alignment, right?

mikeman: Ya, well, I just asked that question (and about the virtual functions) for my own enlightenment, I'm only using this, dare I say it, hack, with straight old classes, no virtuals, no inheritance. The only reason I'm resorting to this hack is because it saves time, and in allocation and deletion, time is not trivial, because it happens a lot, and it needs to happen fast.
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
Quote:Original post by mikeman
Quote:Original post by doynax
...inheritance in itself does not affect anything.

Hmm, is that true? Where are the members of the ancestor stored then?

I meant that inhertiance won't change the layout of the members or add any extra data. The new structure's members will simply be appended right after the old ones, with the necessary padding of course.
The only exception I know of is that inheritance from an empty structure may reduce the original structure's size to zero instead of it's actual size of one (since C++ normally doesn't allow empty structures).
Beware that some old (ancient) compilers store the vtable pointer at the end of the structure for compability with C.

What do you intend to use this assumption for? We may be able to help you find a better solution without losing any performance.
Quote:Original post by SirLuthor
The only reason I'm resorting to this hack is because it saves time...

Chances are, no it doesn't. You will be doing the exact same thing the compiler would have you doing, so you're just making dangerous assumptions for no good reason, and probably making things difficult for the optimizer.

CM
Quote:Original post by doynax
Yes, the are guaranteed to be in order and the first member will appear directly at the beginning of the a non-virtual structure, inheritance in itself does not affect anything.

No, that isn't guaranteed. Only members whose access is specified by the same access specifier are guaranteed to be in order. If you have multiple access specifiers in a class declaration the first of any of the data members declared first in each access specifiers scope may be the first member of the object. And this isn't per access specifier level it's per access specifier. ex:
struct Something {  public:    int a;  public:    int b;};

The standard does not guarantee that either a or b appears first in the object. It could be either.
Quote:Original post by SiCrane
Quote:Original post by doynax
Yes, the are guaranteed to be in order and the first member will appear directly at the beginning of the a non-virtual structure, inheritance in itself does not affect anything.

No, that isn't guaranteed. Only members whose access is specified by the same access specifier are guaranteed to be in order. If you have multiple access specifiers in a class declaration the first of any of the data members declared first in each access specifiers scope may be the first member of the object. And this isn't per access specifier level it's per access specifier. ex:
struct Something {  public:    int a;  public:    int b;};

The standard does not guarantee that either a or b appears first in the object. It could be either.
Interesting..
I guess I shouldn't have presumed that C++ still followed this though, thanks for the correction. I assume that this 'wriggle-room' was introduced to let the compiler rearrange members to avoid unnecessary padding.

BTW do you know of any compilers that actually utilize this exception?
Quote:Original post by Conner McCloud
Chances are, no it doesn't. You will be doing the exact same thing the compiler would have you doing, so you're just making dangerous assumptions for no good reason, and probably making things difficult for the optimizer.

CM

It's funny you should say that, because about 2 minutes before I read this thread again with your reply in it, it occured to me that that would be the case, and that I should just do what makes it easier to maintain [grin] I'm busy restructuring that section of the code as I type this..
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
I believe at least one of the gcc versions, and I think at least one of the icc versions allowed for reordering in place of padding. i.e.:
struct {  public:    int a;    short b;  private:    int c;    short d;};

May be laid out as a, c, b, d so that the struct is 12 bytes instead of 16.

This topic is closed to new replies.

Advertisement