On 11/01/10 13:35, Balog Pal wrote:
[snip]
1.8p5
Unless it is a bitfield (9.6), a most derived object shall have a
nonzero size and shall occupy one or more bytes of storage. Base class
subobjects may have zero size. An object of POD4) type (3.9) shall
occupy contiguous bytes of storage.
Balog,
Would you happen to know the rationale for the different sizes used
for a base object and most derived object? It seems it would save
some space; do, why not save the space?
What would save the space? Making different members of some class have
the same address?
Yes.
Base class subobject is allowed to be of zero size
because in some cases its address can coincide with the address of the
derived object without introducing any ambiguities. Two base classes
[of the same derived class] cannot have the same address. Two members
of the same class cannot have the same address.
Why?
Please elaborate on
your "space saving" idea.
I suppose there's something dangerous about two members of the same
class having the same address, but I don't know what that danger is.
I've read:
http://www.cantrip.org/emptyopt.html
which says:
If you were keeping track of separate objects by their addresses, f.b
and f.a[0] would appear to be the same object. The Standard committee
chose to finesse these issues by forbidding zero-sized addressable
objects.
However, if a program has no need to keep track of separate objects by
their addresses, then what would be the harm of having two members with
the same address?
The real reason I'm interested is because:
https://svn.boost.org/trac/boost/br...ite_storage/pack/container_all_of_aligned.hpp
can have something like 0 sized objects but they're really just
offsets into a buffer. The offset's are cast to the actual type
(properly aligned) and I'm worried that doing that is dangerous
for empty class objects somehow and I'd like to know what that
danger is before it "bites me" ;(
Thanks for any enlightenment you could provide, Victor.
-Larry
PS, to illustrate, the attachment, when run, produces output:
sizeof(empty_class<0>)=1
sizeof(index_inherit<0,empties_inherit>)=1
sizeof(empties_inherit)=1
sizeof(empties_tree_inherit)=2
sizeof(empties_member)=2
sizeof(empties_all_of)=1
sizeof(empties_tree_all_of)=1
sizeof(empties_variant)=8
sizeof(empties_one_of)=1
sizeof(enum_base<index0>::type)=1
p0=0x7fff0fa29def
p1=0x7fff0fa29def
*p0=empty_class<0>const&
*p1=empty_class<1>const&
r0=empty_class<0>const&
r1=empty_class<1>const&
&ea_v=0x7fff0fa29dee
&r0=0x7fff0fa29dee
&r1=0x7fff0fa29dee
r1.get()=1
which illustrates that empty members occupy 1 byte
(the empties_member struct sizeof=2), but empties_inherit
does use EBO resulting in sizeof=1.
The empties_all_of sizeof=1 despite being similar
to empties_member.
However, is there some downside to empties_all_of?