Topic: Layout of base classes within derived classes
Author: "Lance Diduck" <lancediduck@nyc.rr.com>
Date: Tue, 16 Jan 2007 15:57:28 CST Raw View
Francis Glassborow wrote:
> In article <1168877814.343645.229000@a75g2000cwd.googlegroups.com>,
> Lance Diduck <lancediduck@nyc.rr.com> writes
> >struct Base1{};//empty
> >struct Base2{};//empty
> >struct Derived:Base1,Base2{};
> >Most modern compilers will show sizeof(Derived)==sizeof(void*); In
> >other words, the result is squashed into something the size of the
> >smallest addressable unit. So just what does "offset" mean now??
> In that case the size would be 1, or perhaps sizeof(int) it certainly
> would not be sizeof(void *) which has nothing to do with the size of the
> smallest addressable unit.
>
>
> --
> Francis Glassborow ACCU
OK strictly speaking, sizeof(Derived) >0 must hold true. This is so
that it can be addressable. sizeof(void*) is almost always sizeof(int),
but of course does not have to be. Some compilers would show
sizeof(Derived)== 1, however, being objects they are likely aligned in
memory as objects, and not char, effectivley aligning just like a
pointer value would be aligned. But of course all this is subject to
compiler vendor and options.
The interesting point is that sizeof(Derived) is not necessarily
sizeof(Base1)+sizeof(Base2), making it look as if Base1 and Base2
subobjects overlap, therefore the concept of "offset" is turned on it
head. It is certainly a different answer than
struct Derived2 {Base1 b;Base2 c;};
Now Base1 and Base2 should (given that you don't have a compiler with
the elusive "Empty Member Optimization") not overlap. In other words,
sizeof(Derived2) <=sizeof(Derived)
---
[ 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: "Lance Diduck" <lancediduck@nyc.rr.com>
Date: Tue, 16 Jan 2007 16:58:40 CST Raw View
Francis Glassborow wrote:
> In article <1168877814.343645.229000@a75g2000cwd.googlegroups.com>,
> Lance Diduck <lancediduck@nyc.rr.com> writes
> >struct Base1{};//empty
> >struct Base2{};//empty
> >struct Derived:Base1,Base2{};
> >Most modern compilers will show sizeof(Derived)==sizeof(void*); In
> >other words, the result is squashed into something the size of the
> >smallest addressable unit. So just what does "offset" mean now??
> In that case the size would be 1, or perhaps sizeof(int) it certainly
> would not be sizeof(void *) which has nothing to do with the size of the
> smallest addressable unit.
>
>
> --
> Francis Glassborow ACCU
> Author of 'You Can Do It!' and "You Can Program in C++"
> see http://www.spellen.org/youcandoit
> For project ideas and contributions: http://www.spellen.org/youcandoit/projects
OK strictly speaking, sizeof(Derived) >0 must hold true. This is so
that it can be addressable. sizeof(void*) is almost always sizeof(int),
but of course does not have to be. Some compilers would show
sizeof(Derived)== 1, however, being objects they are likely aligned in
memory as objects, and not char, effectivley aligning just like a
pointer value would be aligned. But of course all this is subject to
compiler vendor and options.
The interesting point is that sizeof(Derived) is not necessarily
sizeof(Base1)+sizeof(Base2), making it look as if Base1 and Base2
subobjects overlap, therefore the concept of "offset" is turned on it
head. It is certainly a different answer than
struct Derived2 {Base1 b;Base2 c;};
Now Base1 and Base2 should (given that you don't have a compiler with
the elusive "Empty Member Optimization") not overlap. In other words,
sizeof(Derived2) <=sizeof(Derived)
---
[ 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: loufoque@remove.gmail.com (Mathias Gaunard)
Date: Wed, 17 Jan 2007 04:11:40 GMT Raw View
Francis Glassborow wrote:
> In that case the size would be 1, or perhaps sizeof(int) it certainly
> would not be sizeof(void *) which has nothing to do with the size of the
> smallest addressable unit.
Didn't sizeof(int) use to be (before 64 bits architecture were
introduced) the size of the word rather?
---
[ 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: kuyper@wizard.net
Date: Wed, 17 Jan 2007 10:16:58 CST Raw View
Mathias Gaunard wrote:
> Francis Glassborow wrote:
>
> > In that case the size would be 1, or perhaps sizeof(int) it certainly
> > would not be sizeof(void *) which has nothing to do with the size of the
> > smallest addressable unit.
>
> Didn't sizeof(int) use to be (before 64 bits architecture were
> introduced) the size of the word rather?
The most general statement you can make is that int is a reasonably
fast type with at least 16 bits. Making it the size of a word tends to
help with the "fast" part, if the word size is big enough, but that is
not and never has been a requirement.
---
[ 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: "Lance Diduck" <lancediduck@nyc.rr.com>
Date: Sat, 13 Jan 2007 13:23:23 CST Raw View
Michael Norrish wrote:
> Is there language in the standard that forces the layout of base
> classes within a descendent to be the same, independent of whether or
> not the descendent is most derived?
> Thanks,
> Michael.
You may want to pick up a copy of Lippmann's "Inside the C++ Object
Model" Although written in the mid 90's it is still very relevant
---
[ 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: Michael Norrish <michael.norrish@nicta.com.au>
Date: Sun, 14 Jan 2007 18:08:32 CST Raw View
Lance Diduck wrote:
> Michael Norrish wrote:
>> Is there language in the standard that forces the layout of base
>> classes within a descendent to be the same, independent of whether or
>> not the descendent is most derived?
> You may want to pick up a copy of Lippmann's "Inside the C++ Object
> Model" Although written in the mid 90's it is still very relevant
Thanks for the reference!
It seems pretty clear that the answer to my question is "no", but I
expect Lippman talks mainly about sensible implementations of the
model rather than bizarre things that the standard implicitly permits.
Or are there implementations that use object layout tables to allow
non-virtual base classes at different places?
Michael.
---
[ 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: Mon, 15 Jan 2007 00:07:55 GMT Raw View
In article <1168698501.778254.272280@v45g2000cwv.googlegroups.com>,
Lance Diduck <lancediduck@nyc.rr.com> writes
>Michael Norrish wrote:
>> Is there language in the standard that forces the layout of base
>> classes within a descendent to be the same, independent of whether or
>> not the descendent is most derived?
>> Thanks,
>> Michael.
>You may want to pick up a copy of Lippmann's "Inside the C++ Object
>Model" Although written in the mid 90's it is still very relevant
Y all means read that book but remember that Lippmann is actually
writing about a specific Object Model (that use by AT&T CFront compiler)
and not the C++ Object Model (of which there are a variety that all meet
the requirements of the C++ Standard)
--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ 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: Mon, 15 Jan 2007 17:05:26 GMT Raw View
In article <45aac134$1@clarion.carno.net.au>, Michael Norrish
<michael.norrish@nicta.com.au> writes
>Thanks for the reference!
>
>It seems pretty clear that the answer to my question is "no", but I
>expect Lippman talks mainly about sensible implementations of the model
>rather than bizarre things that the standard implicitly permits. Or
>are there implementations that use object layout tables to allow
>non-virtual base classes at different places?
IIRC there have been various different layouts used for classes with
multiple bases. The special circumstance for classes with virtual bases
is that know the layout for one derived class tells you little about the
layout for classed derived from that one. IOWs the layout for an object
of a type that includes a virtual base class tells you nothing about the
layout of a subobject of the same type in another object of a different
type.
There are other issues such as the possibility that padding space in a
base class is used for data in a derived class (i.e. the Standard
permits data for a base class and a derived class to be interwoven)
--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ 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: "Lance Diduck" <lancediduck@nyc.rr.com>
Date: Tue, 16 Jan 2007 10:40:00 CST Raw View
Michael Norrish wrote:
> Lance Diduck wrote:
> > Michael Norrish wrote:
> >> Is there language in the standard that forces the layout of base
> >> classes within a descendent to be the same, independent of whether or
> >> not the descendent is most derived?
>
> > You may want to pick up a copy of Lippmann's "Inside the C++ Object
> > Model" Although written in the mid 90's it is still very relevant
>
> Thanks for the reference!
>
> It seems pretty clear that the answer to my question is "no", but I
> expect Lippman talks mainly about sensible implementations of the
> model rather than bizarre things that the standard implicitly permits.
> Or are there implementations that use object layout tables to allow
> non-virtual base classes at different places?
>
> Michael.
Another excellent tratement of this subject is in Wilson "Imperfect
C++." See chaperts aon Empty Base and Empry Derived optimizations, and
"Object Across Borders."
However I think that the question is ill formed. Consider this
examples:
struct Base1{};//empty
struct Base2{};//empty
struct Derived:Base1,Base2{};
Most modern compilers will show sizeof(Derived)==sizeof(void*); In
other words, the result is squashed into something the size of the
smallest addressable unit. So just what does "offset" mean now??
Most object layouts are driven by interoperability concerns more than
anything. For instance, if I had a binary library from compiler a.x,
could I link it with another link library from compiler b.y -- could
just be the same compiler with different build options. This is
especially prominent on Windows platforms, since the COM model requires
a certain binary layout, and any compiler that wants to produce a COM
object will have to use that layout.
So there really is no magic in how C++ objects are laid out. If a
compiler did not have to worry about interoperability, versioning,
compiler switches, optimizations and the like, C++ object layout can be
very straighforward. A C++ compiler as a student project perhaps could
come up with odd object layouts. But we do have to worry about that
stuff in commercial systems..
Hope that helps
---
[ 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: Tue, 16 Jan 2007 18:45:58 GMT Raw View
In article <1168877814.343645.229000@a75g2000cwd.googlegroups.com>,
Lance Diduck <lancediduck@nyc.rr.com> writes
>struct Base1{};//empty
>struct Base2{};//empty
>struct Derived:Base1,Base2{};
>Most modern compilers will show sizeof(Derived)==sizeof(void*); In
>other words, the result is squashed into something the size of the
>smallest addressable unit. So just what does "offset" mean now??
In that case the size would be 1, or perhaps sizeof(int) it certainly
would not be sizeof(void *) which has nothing to do with the size of the
smallest addressable unit.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ 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: Michael Norrish <michael.norrish@nicta.com.au>
Date: Sun, 7 Jan 2007 22:25:55 CST Raw View
Is there language in the standard that forces the layout of base
classes within a descendent to be the same, independent of whether or
not the descendent is most derived?
For example, if we have
class B1 { public: int bfld; ... } ;
class B2 { ... } ;
class V { ... } ;
class D1 : public B1, public B2, virtual public V { ... } ;
class F : public D1 { ... } ;
I think we can calculate an approximation of the offset of B1 within
a D1 with the following:
ptrdiff_t b1_off(const D1 &d)
{
const char *cptr1 = (const char *)&d;
const char *cptr2 = (const char *)&d.bfld;
return cptr2 - cptr1;
}
If I then have
bool test()
{
F fobj; D1 dobj;
return (b1_off(fobj) == b1_off(dobj));
}
is this required to return true?
Or is this program undefined because the two pointers I subtract in
b1_off are not pointers to the same array object? If so, is there any
way at all of "seeing" the offset of base objects?
Thanks,
Michael.
---
[ 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: loufoque@remove.gmail.com (Mathias Gaunard)
Date: Mon, 8 Jan 2007 15:17:28 GMT Raw View
Michael Norrish wrote:
> I think we can calculate an approximation of the offset of B1 within
> a D1 with the following:
>
> ptrdiff_t b1_off(const D1 &d)
> {
> const char *cptr1 = (const char *)&d;
> const char *cptr2 = (const char *)&d.bfld;
> return cptr2 - cptr1;
> }
We can see that would only work if B1::bfld was at the same address as B1.
#include <iostream>
struct B1
{
virtual ~B1() {}
int bfld;
};
int main()
{
B1 b;
std::cout << (reinterpret_cast<void*>(&b) ==
reinterpret_cast<void*>(&b.bfld)) << std::endl;
}
I get 0 on my compiler.
---
[ 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: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 8 Jan 2007 09:52:23 CST Raw View
Michael Norrish wrote:
> Or is this program undefined because the two pointers I subtract in
> b1_off are not pointers to the same array object? If so, is there any
> way at all of "seeing" the offset of base objects?
A C++ program would typically use a member data pointer instead of an
offset value to access a particular sub-object of a class given a
pointer to an instance of the class. Is there a reason why a member
data pointer would not work for your purposes?
Greg
---
[ 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: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 8 Jan 2007 10:15:57 CST Raw View
Michael Norrish wrote:
> Or is this program undefined because the two pointers I subtract in
> b1_off are not pointers to the same array object? If so, is there any
> way at all of "seeing" the offset of base objects?
A C++ program would typically use a member data pointer instead of an
offset value to access a particular sub-object of a class given a
pointer to an instance of the class. Is there a reason why a member
data pointer would not work for your purposes?
Greg
---
[ 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: stephen.clamage@sun.com
Date: Mon, 8 Jan 2007 11:19:50 CST Raw View
On Sun, 7 Jan 2007 22:25:55 CST, Michael Norrish
<michael.norrish@nicta.com.au> wrote:
>Is there language in the standard that forces the layout of base
>classes within a descendent to be the same, independent of whether or
>not the descendent is most derived?
The standard says nothing about how base classes are laid out.
In particular, sometimes the layout must depend on the place in the
hierarchy. Example:
class Z {
...
};
class A : virtual public Z {
...
};
class B : virtual public Z {
...
};
class C : public A, public B {
...
};
Suppose in an A object, the Z portion is at offset OA, and in a B
object it is at offset OB. There is only one copy of Z in a C object.
It cannot simultaneously be at offset OA from the A portion and at
offset OB from the B portion. At least one of these offsets must be
different when the entire object is of type C.
You can subtract pointers that both point into the same complete
object, but for class objects, you can't make many assumptions about
the result.
The pointer-to-member type was introduced to avoid having to use
offsets and pointer arithmetic in most cases.
---
Steve Clamage
---
[ 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: loufoque@remove.gmail.com (Mathias Gaunard)
Date: Mon, 8 Jan 2007 19:14:07 GMT Raw View
Greg Herlihy wrote:
> A C++ program would typically use a member data pointer instead of an
> offset value to access a particular sub-object of a class given a
> pointer to an instance of the class. Is there a reason why a member
> data pointer would not work for your purposes?
It needlessly adds memory usage.
This was discussed earlier in a thread about C#-like Proprieties.
---
[ 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: kuyper@wizard.net
Date: Mon, 8 Jan 2007 18:05:51 CST Raw View
Mathias Gaunard wrote:
> Greg Herlihy wrote:
>
> > A C++ program would typically use a member data pointer instead of an
> > offset value to access a particular sub-object of a class given a
> > pointer to an instance of the class. Is there a reason why a member
> > data pointer would not work for your purposes?
>
> It needlessly adds memory usage.
> This was discussed earlier in a thread about C#-like Proprieties.
Could you please expand upon that explanation? I'm not sure which
thread you're referring to; I found one message you sent with "C#" in
the subject line, but I didn't see how it was relevant.
---
[ 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: Michael Norrish <michael.norrish@nicta.com.au>
Date: Mon, 8 Jan 2007 18:29:13 CST Raw View
stephen.clamage@sun.com wrote:
> On Sun, 7 Jan 2007 22:25:55 CST, Michael Norrish
> <michael.norrish@nicta.com.au> wrote:
>
>> Is there language in the standard that forces the layout of base
>> classes within a descendent to be the same, independent of whether or
>> not the descendent is most derived?
> The standard says nothing about how base classes are laid out.
> In particular, sometimes the layout must depend on the place in the
> hierarchy. Example:
> class Z {
> ...
> };
> class A : virtual public Z {
> ...
> };
> class B : virtual public Z {
> ...
> };
> class C : public A, public B {
> ...
> };
> Suppose in an A object, the Z portion is at offset OA, and in a B
> object it is at offset OB. There is only one copy of Z in a C
> object. It cannot simultaneously be at offset OA from the A portion
> and at offset OB from the B portion. At least one of these offsets
> must be different when the entire object is of type C.
Indeed. As you say, the layout of the virtual bases can be different
depending on most-derived status. But my question is: must the base
classes always be laid out in the same (unspecified) way, ignoring
whether or not the derived class is most derived? This is why the
example needs both three levels of hierarchy and non-virtual ancestors
at the most-ancestral level.
If D has three ancestors, one of which is virtual, and D is then the
ancestor of D', must the D that occurs inside D' (i.e., not a most
derived D) lay its non-virtual ancestors out in the same way as a
most-derived D?
Or is it impossible to tell in a program that avoids undefined
behaviour? (That is why my original post posited pointer subtraction
as a way of finding out. I'm sorry it distracted people into telling
me about member pointers, and the fact that first members are not
necessarily at the base of non POD classes.)
I'm interested in knowing whether the standard implicitly requires
implementations to lay out objects so that the virtual bases always
come last in the layout, and so that non-static data members and
non-virtual bases are always laid out in the same way before any
virtual bases. I find it hard to imagine an implementation that did
this any differently, but that's not much of a proof!
------------------------------
> You can subtract pointers that both point into the same complete
> object, but for class objects, you can't make many assumptions about
> the result.
This is a tangent, but really? In 5.7 paragraph 6:
"Unless both pointers point to elements of the same array object, or
one past the last element of the array object, the behaviour is
undefined."
If I have
struct s { int x, y; };
it doesn't seem clear that I can write
&x - &y
because there is no common array. I can compare &x and &y (by 5.9
para 2), but it doesn't seem as if I can subtract them.
Best wishes,
Michael.
---
[ 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: wade@stoner.com
Date: Tue, 9 Jan 2007 09:36:38 CST Raw View
Michael Norrish wrote:
> Indeed. As you say, the layout of the virtual bases can be different
> depending on most-derived status. But my question is: must the base
> classes always be laid out in the same (unspecified) way, ignoring
> whether or not the derived class is most derived? This is why the
> example needs both three levels of hierarchy and non-virtual ancestors
> at the most-ancestral level.
Part of the layout of a class is the layout of its base classes. SC
was demonstrating that the base classes must have the freedom to "move
around" for different most-derived classes.
I think you are asking if the non-static non-reference data members of
a class (those defined in the class, not in some base) are free to move
around, relative to the class. For POD the answer is no. AFAICT, for
non-pod, a compiler could put data members in different locations for
different instances (even if two instances had the same most-derived
type). However, it seems difficult to do, and of limited benefit, so I
don't expect any real compilers do it.
> Or is it impossible to tell in a program that avoids undefined
> behaviour?
Without UB, for a given l-value instance of an object, a program can
determine:
a) The order of the data elements.
b) If two data elements are adjacent (no space between them).
Use reinterpret cast to convert elements to (const volatile char&), and
then compare their addresses using std::less.
> I'm interested in knowing whether the standard implicitly requires
> implementations to lay out objects so that the virtual bases always
> come last in the layout, and so that non-static data members and
> non-virtual bases are always laid out in the same way before any
> virtual bases. I find it hard to imagine an implementation that did
> this any differently, but that's not much of a proof!
There is no such requirement. If the first implementation-element of
an object is a layout-table-pointer, then there is a lot of freedom in
how the rest of the object is positioned. We don't expect compilers to
use this freedom, because it has time and space penalties, but it is
certainly allowed by the standard.
To a certain extent the answer to this kind of question depends on what
your program tries to find out.
std::pair<int,int> a;
{
std::pair<int,int> b = std::make_pair(1,2);
a.first = b.second;
a.second = b.first;
}
...
Since my program never tries to determine the layout of 'b', the
compiler is free to use any layout it wants (including not having any
'b' object at all). The ... code might observe the layout and/or
values of 'a', so the compiler might be more restricted in its layout.
---
[ 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: michael.norrish@nicta.com.au (Michael Norrish)
Date: Tue, 9 Jan 2007 22:26:49 GMT Raw View
wade@stoner.com wrote:
> Part of the layout of a class is the layout of its base classes. SC
> was demonstrating that the base classes must have the freedom to
> "move around" for different most-derived classes.
I think he only demonstrated that the *virtual* bases had to be free
to move around.
> I think you are asking if the non-static non-reference data members
> of a class (those defined in the class, not in some base) are free
> to move around, relative to the class.
Actually, I'm more interested in the virtual and non-virtual bases.
>> I'm interested in knowing whether the standard implicitly requires
>> implementations to lay out objects so that the virtual bases always
>> come last in the layout, and so that non-static data members and
>> non-virtual bases are always laid out in the same way before any
>> virtual bases. I find it hard to imagine an implementation that
>> did this any differently, but that's not much of a proof!
> There is no such requirement. If the first implementation-element of
> an object is a layout-table-pointer, then there is a lot of freedom in
> how the rest of the object is positioned. We don't expect compilers to
> use this freedom, because it has time and space penalties, but it is
> certainly allowed by the standard.
Ah yes. And in this scheme, I guess the application of
pointers-to-members would consult the layout tables of the objects to
which they were applied. (The pointers-to-members might simply be
indexes in those layout tables).
> To a certain extent the answer to this kind of question depends on
> what your program tries to find out.
> std::pair<int,int> a;
> {
> std::pair<int,int> b = std::make_pair(1,2);
> a.first = b.second;
> a.second = b.first;
> }
> ...
> Since my program never tries to determine the layout of 'b', the
> compiler is free to use any layout it wants (including not having
> any 'b' object at all). The ... code might observe the layout
> and/or values of 'a', so the compiler might be more restricted in
> its layout.
True! The wonders of the as-if rule...
Thanks,
Michael.
---
[ 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 ]