Boost logo

Boost :

From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2007-10-02 14:21:12


Marco wrote:
> What I'm interesting is if the standard says something about declaration
> order of struct fields and their storage order in memory.
It does. It says that members of a struct or class (even non-POD ones,
which I think is a useless restriction) that have no intervening access
specifier are stored in memory in the same order as they are declared.
9.2/12 says:
> Nonstatic data members of a (non-union) class declared without an
> intervening /access-specifier/ are allocated so that later members have
> higher addresses within a class object. The order of allocation of
> nonstatic data members separated by an /access-specifier/ is unspecified. Implementation alignment requirements might
> cause two adjacent members not to be allocated immediately after each
> other; so might requirements for space for managing virtual functions and virtual base classes.

That means:

class foo
{
  int i1;
  int i2;
public:
  int i3;
  int i4;
public:
  int i5;
};

->

&i1 < &i2 == true
&i3 < &i4 == true
&i1 < &i3 unspecified
&i3 < &i5 unspecified

In particular, although no compiler I know of does it, an implementation
can reorder fields to e.g. make the allocation pattern more efficient:

class inefficient
{
  char c1;
private:
  int i1;
private:
  char c2;
private:
  int c2;
};

Naively, on a typical 32-bit platform, sizeof(inefficent) would be 16.
But with all the intervening access specifiers, a compiler would be
allowed to arrange the members as i1,i2,c1,c2 and make
sizeof(inefficient) 12.

What I personally don't understand is why private members - or in fact
all members of non-PODs - can't always be re-ordered. It's not like
anyone should ever depend on their order. It probably was C
compatibility that there were any guarantees at all.

Sebastian Redl


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk