Topic: Hiding Variables within a class
Author: bart@ingen.ddns.info (Bart van Ingen Schenau)
Date: Mon, 29 May 2006 19:05:20 GMT Raw View
[x-posted to both alt.comp.lang.learn.c-c++ and comp.std.c++]
Francis Glassborow wrote:
>
> The point at issue is this:
>
> struct A {
> char a;
> int b;
> char c;
> };
>
> Is a POD and must be laid out in memory with the addresses of a, b and
> c in that order. Padding is allowed between a and b and between b and
> c and at the end. On some implementations that will give sizeof A ==
> 12 (just as an example)
>
> struct B {
> public:
> char a;
> public:
> int b;
> public:
> char c;
> };
>
> I suspect is not a POD (and does not abide by the rules for common
> initial sequences when placed in a union with A) the addresses of a, b
> and c can be in any order.
I can't find anything in the standard that rules struct B to be a
non-POD struct.
But on the other hand, the explicit allowance to re-order the members of
struct B makes that the properties of struct B do not match the
properties that most people expect of a POD struct (in particular, the
guaranteed order of members).
To me, this issue is sufficiently unclear that it deserves a Defect
Report, but I would like to hear the opinions of other knowledgeable
people first.
> I think any one of them is allowed to have
> the same address as an instance of B would have. Of course the rules
> require that one of them has such an address because no padding is
> allowed at the start of an object.
Except that for a non-POD struct, there can also be some internal
bookkeeping information (such as v-tables) at the beginning of the
memory area occupied by the structure.
Therefor, it is perfectly valid that the assert in this snippet fires:
struct B b;
assert((&b.a == &b) || (&b.b == &b) || (&b.c == &b));
>
>
> An optimising compiler might layout a B instance as a,c, b and so
> reduce padding to align b as an int.
>
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Tue, 30 May 2006 12:52:25 CST Raw View
Bart van Ingen Schenau wrote:
> [x-posted to both alt.comp.lang.learn.c-c++ and comp.std.c++]
>
> Francis Glassborow wrote:
>
> >
> > The point at issue is this:
> >
> > struct A {
> > char a;
> > int b;
> > char c;
> > };
> >
> > Is a POD and must be laid out in memory with the addresses of a, b and
> > c in that order. Padding is allowed between a and b and between b and
> > c and at the end. On some implementations that will give sizeof A ==
> > 12 (just as an example)
> >
> > struct B {
> > public:
> > char a;
> > public:
> > int b;
> > public:
> > char c;
> > };
> >
> > I suspect is not a POD (and does not abide by the rules for common
> > initial sequences when placed in a union with A) the addresses of a, b
> > and c can be in any order.
>
9.2-12
"
12Nonstatic 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
(_class.access.spec_). 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
(_class.virtual_) and virtual base classes (_class.mi_)."
Actually, I never understood why the ISO standard specified that stuff
for non-POD types.
It reduces the implementation freedom, thus, for instance:
class X {
private:
double xf;
int xi;
double yf;
int yi;
char c1;
int c2;
char c2;
public:
X();
};
On many implementations, I'm pretty sure that either performances, or
the size of the structure would be much smaller if members were
reordered such as big objects be put first, and then smaller objects,
like that:
class X {
private:
double xf;
double yf;
int xi;
int yi;
int c2;
char c1;
char c2;
public:
X();
};
However this optimization is forbidden.
It might be seen as a real problem, because the programmer has not
always a total control on the order of members in a structure, because
of dependent members (i.e. a non-static data member whose constructor
takes a pointer/reference/value of another member), the order of
members in a class is more or less defined be non-memory factors.
Fortunately, it is still possible to define:
class X {
private: double xf;
private: int xi;
private: double yf;
private: int yi;
private: char c1;
private: int c2;
private: char c2;
public:
X();
};
Which allows compiler optimizations.
But that's weird.
I find it quite confusing that semantics depend on such dumb access
specifiers.
But since it is in the standard, I don't think we can remove this
paragraph without seriously harming backward compatibility.
> I can't find anything in the standard that rules struct B to be a
> non-POD struct.
B is a POD-struct. I'm sure that it was the intent of the comittee...
Otherwise rules for knowing what is a POD-struct would be extremely
non-intuitive and error prone.
> But on the other hand, the explicit allowance to re-order the members of
> struct B makes that the properties of struct B do not match the
> properties that most people expect of a POD struct (in particular, the
> guaranteed order of members).
>
Yeah, an implementation is "allowed" to reorder the members.
But, as you know, it is not really possible in a sensible
implementation since POD types must verify properties such as access of
common shared initial sequences in an union.
> To me, this issue is sufficiently unclear that it deserves a Defect
> Report, but I would like to hear the opinions of other knowledgeable
> people first.
>
I think so too.
Let me explain.
First, IMHO, it is perfectly clear that this structure is POD and must
remain a POD structure.
I think that it was the intent of the comittee.
But I also think that the comittee intended that implementations were
not allowed to reorder members of a POD struct.
Actually, as the standard is defined, an implementation is effectively
allowed (and really *can*) to reorder members of POD struct.
I think that such implementation would require extra meta-data stored
in unions (such as which field of which struct is currently "active"),
and perhaps even more complex meta-data that might be possible with a
C++ interpreted implementation.
But I think too that :
1) No implementation currently do that.
2) No sensible implementation will ever do that.
3) The intent of the comittee was, very probably, to forbid such
implementation.
So, I think that it is a defect and the C++ comittee should add a
paragraph in [class.mem] stating something like (based on the wording
of class.mem-12):
Nonstatic data members of a POD-struct are allocated so that later
members have
higher addresses within a class object.
Footnote :The order of allocation of nonstatic data members
separated by an access-specifier is well-defined, unlike with non-POD
structs
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Jens_M=FCller?= <usenet-01-2006@tessarakt.de>
Date: Tue, 30 May 2006 15:58:15 CST Raw View
SuperKoko schrieb:
> 9.2-12
> "
> 12Nonstatic 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
> (_class.access.spec_). 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
> (_class.virtual_) and virtual base classes (_class.mi_)."
Is it allowed to mix data members from different access-specifier blocks
as long as the relative order of data members in one access-specifier
block is preserved?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Wed, 31 May 2006 06:57:28 GMT Raw View
In article <4e3m8rF1d4l9gU1@individual.net>, Jens M=FCller=20
<usenet-01-2006@tessarakt.de> writes
>Is it allowed to mix data members from different access-specifier blocks
>as long as the relative order of data members in one access-specifier
>block is preserved?
AIUI, yes.
--=20
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/pr=
ojects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: bart@ingen.ddns.info (Bart van Ingen Schenau)
Date: Wed, 31 May 2006 21:46:18 GMT Raw View
SuperKoko wrote:
>
> Bart van Ingen Schenau wrote:
>> [x-posted to both alt.comp.lang.learn.c-c++ and comp.std.c++]
>>
>> Francis Glassborow wrote:
>> > struct B {
>> > public:
>> > char a;
>> > public:
>> > int b;
>> > public:
>> > char c;
>> > };
>> >
>> > I suspect is not a POD (and does not abide by the rules for common
>> > initial sequences when placed in a union with A) the addresses of
>> > a, b and c can be in any order.
>>
<snip>
>> I can't find anything in the standard that rules struct B to be a
>> non-POD struct.
> B is a POD-struct. I'm sure that it was the intent of the comittee...
> Otherwise rules for knowing what is a POD-struct would be extremely
> non-intuitive and error prone.
My gut feeling says that B is/should be a non-POD struct, but as I said
before, I can't back it up with a quote from the standard.
>
>> But on the other hand, the explicit allowance to re-order the members
>> of struct B makes that the properties of struct B do not match the
>> properties that most people expect of a POD struct (in particular,
>> the guaranteed order of members).
>>
> Yeah, an implementation is "allowed" to reorder the members.
> But, as you know, it is not really possible in a sensible
> implementation since POD types must verify properties such as access
> of common shared initial sequences in an union.
>
>> To me, this issue is sufficiently unclear that it deserves a Defect
>> Report, but I would like to hear the opinions of other knowledgeable
>> people first.
>>
> I think so too.
> Let me explain.
>
> First, IMHO, it is perfectly clear that this structure is POD and must
> remain a POD structure.
> I think that it was the intent of the comittee.
> But I also think that the comittee intended that implementations were
> not allowed to reorder members of a POD struct.
Then why the explicit allowance?
If the order of the members of a POD struct was to be fully specified,
it could easily have been done with wording like:
"Nonstatic data members of a POD-struct are allocated so that later
members have higher addresses within a class object. The order of
allocation of nonstatic data members of a non-POD class is unspecified.
Implementation alignment requirements might cause two adjacent members
of a POD-struct not to be allocated immediately after each other."
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]