Topic: storage order of inherited classes
Author: kanze@gabi-soft.de (James Kanze)
Date: 31 Aug 2001 18:19:43 GMT Raw View
plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: posting.google.com 999256906 11596 127.0.0.1 (31 Aug 2001 11:21:46
GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: 31 Aug 2001 11:21:46 GMT
Content-Length: 2102
ReSent-Date: Fri, 31 Aug 2001 10:01:48 -0700 (PDT)
ReSent-From: Steve Clamage <clamage@eng.sun.com>
ReSent-To: <c++-submit@netlab.cs.rpi.edu>
ReSent-Subject: Re: storage order of inherited classes
ReSent-Message-ID: <Pine.SOL.4.33.0108311001480.14848@taumet>
"Gaurav Sareen" <albelakela@hotmail.com> wrote in message
news:<mQ7j7.511357$lq1.104203497@typhoon.austin.rr.com>...
> > > This IMO is one of the big reasons why java can be "safer" than
> > > C++ is that the runtime layout of the classes is fixed.
> > Just curious. I can see how this makes Java more portable than
> > C++, at least for some definitions of portable, but how does is
> > make the language "safer"?
> In the sense that you cant look at a compiled class and make sure
> its well formed.
Can you. I don't think you can look at the layout of a class in
either language.
> I was talking in terms of the VM being able to do verification of
> the byte code, which basically means that it can make sure that the
> code is not ill formed, and wont cause some of the unsafe memory
> corruption that can happen by executing native code. I agree some of
> the java safety comes at the cost of (slow) runtime checks, and even
> the above checking while loading may be slow but it sure is safer.
This is a totally different issue. It has nothing to do with a fixed
runtime layout; it has to do with the fact that a Java .class file
typically contains a lot more information than a C++ object or library
file. If you prefer, it isn't the runtime layout that is fixed, so
much as the fact that the actual hardware level access is only
generated at link time, after program verification.
This is a two edged sword. It means that dynamically loaded libraries
are safer in Java than in C++. But it also means that every class is
a separate dynamically loaded library; you can't static link at all.
And static linking is safer than any dynamic linking; there's just
nothing that can go wrong with it at run-time. In practice, I don't
normally use dynamically linked libraries at all in C++, except for a
little GUI work.
--
James Kanze mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
-- Conseils en informatique orient e objet
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany, T l.: +49 (0)69 19 86 27
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Steve Clamage <Stephen.Clamage@Sun.COM>
Date: 29 Aug 2001 04:55:29 GMT Raw View
On 28 Aug 2001, Jack Klein wrote:
>
> A base class appears before any of the additional data items added in
> a derived class in a case like this.
Although that is a common layout scheme, it is certainly not a
requirement.
> Otherwise it would not be
> possible for a pointer to a base class to point to a derived class
> object. The first sizeof(base class) bytes of the derived class must
> be the instance of the base class in the derived class.
If that were true, how would you implement multiple inheritance?
If more than one direct base class has non-zero size, you can't
put all of them at the beginning of the object!
There is no requirement that Derived* and Base* refer to the
same address. The requirement is that a Derived* converted to
a Base* then points to the Base portion of the object. Pointer
conversions are allowed to involve runtime code that changes
the bits in the pointer value. In the case of multiple
inheritance and virtual base classes, the conversion MUST
involve a change.
--
Steve Clamage, stephen.clamage@sun.com
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: kanze@gabi-soft.de (James Kanze)
Date: 29 Aug 2001 04:55:28 GMT Raw View
"Gaurav Sareen" <albelakela@hotmail.com> wrote in message
news:<XPai7.507226$lq1.100246902@typhoon.austin.rr.com>...
> This IMO is one of the big reasons why java can be "safer" than C++
> is that the runtime layout of the classes is fixed.
Just curious. I can see how this makes Java more portable than C++,
at least for some definitions of portable, but how does is make the
language "safer"? (I'll admit that in 10 years of C++, I've never
seen or heard of an error due to different compilers using different
runtime layouts. Generally, different compilers use different
mangling schemes, so code from different compilers won't even link
together, much less cause a run-time error.)
--
James Kanze mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
-- Conseils en informatique orient e objet
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany, T l.: +49 (0)69 19 86 27
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 29 Aug 2001 04:55:29 GMT Raw View
In article <5pqjot40to3q1rcrhokquq3e6k9s1sv2k3@4ax.com>, Jack Klein
<jackklein@spamcop.net> writes
>A base class appears before any of the additional data items added in
>a derived class in a case like this. Otherwise it would not be
>possible for a pointer to a base class to point to a derived class
>object. The first sizeof(base class) bytes of the derived class must
>be the instance of the base class in the derived class.
So how do you propose to implement multiple inheritance? Or inheritance
involving a virtual base, or a polymorphic class derived from a simple
base class etc. ?
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: deepa@eventhelix.com (Deepa Ahluwalia)
Date: 29 Aug 2001 21:40:57 GMT Raw View
With most compilers elements of class A would be included before B.
Typical order is:
Elements of A
Vtable pointer (if present)
Elements of B
Check the following articles for ordering of elements:
http://www.eventhelix.com/RealtimeMantra/Basics/ComparingCPPAndCPerformance.htm
http://www.eventhelix.com/RealtimeMantra/Basics/ComparingCPPAndCPerformance2.htm
Deepa
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Gaurav Sareen" <albelakela@hotmail.com>
Date: 30 Aug 2001 17:43:15 GMT Raw View
> > This IMO is one of the big reasons why java can be "safer" than C++
> > is that the runtime layout of the classes is fixed.
>
> Just curious. I can see how this makes Java more portable than C++,
> at least for some definitions of portable, but how does is make the
> language "safer"?
In the sense that you cant look at a compiled class and make sure its well
formed.
I was talking in terms of the VM being able to do verification of the byte
code, which basically means that it can make sure that the code is not ill
formed, and wont cause some of the unsafe memory corruption that can happen
by executing native code. I agree some of the java safety comes at the cost
of (slow) runtime checks, and even the above checking while loading may be
slow but it sure is safer.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Fray Bentos" <LOVELYSPAMfraybentos@wonderfulspamphreaker.net>
Date: 25 Aug 2001 23:50:42 GMT Raw View
Hey peeps.
Im involved in optimising a few C++ classes that interface with OpenGL
I was wondering if the memory storage order of class members is
standardised ?
Will the array j from the derived class B always be stored before i from the
base class A ?
------------------------8<---------------------
#include <iostream>
class A
{
public:
int i[4];
A(int a, int b, int c, int d)
{
i[0] = a*10 ; i[1] = b*10;
i[2] = c*10 ; i[3] = d*10;
}
};
class B : public A
{
public:
int j[4];
B(int a, int b, int c, int d) : A(a, b, c, d)
{
j[0] = a; j[1] = b;
j[2] = c; j[3] = d;
}
};
main()
{
B b(1, 2, 3, 4);
int *ptr_b = reinterpret_cast<int*>(&b);
for(int i=0; i<sizeof(b) / sizeof(int); i++)
std::cout << ptr_b[i] << std::endl;
}
------------------------8<---------------------
output:
10
20
30
40
1
2
3
4
Thanks
--
- | Fray B | -
Conviction is a greater enemy of the truth than lies. (Nietzsche)
ICQ #124994627
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 27 Aug 2001 14:55:42 GMT Raw View
Fray Bentos wrote:
>
> Hey peeps.
>
> Im involved in optimising a few C++ classes that interface with OpenGL
> I was wondering if the memory storage order of class members is
> standardised ?
Yes, but only to a degree:
9.2p12: "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
(11.1). 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 (10.3) and virtual
base classes (10.1)."
10.1p3: "The order in which the base class subobjects are allocated in
the most derived object (1.8) is unspecified. ..."
> Will the array j from the derived class B always be stored before i from the
> base class A ?
Because of 10.1p3, there's no guarantee about the position of j relative
to i.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Justin Randall" <jrandall@verant.com>
Date: 27 Aug 2001 14:55:43 GMT Raw View
"Fray Bentos" <LOVELYSPAMfraybentos@wonderfulspamphreaker.net> wrote in
message news:MpMh7.6544$3f.1248650@news2-win.server.ntlworld.com...
>
> Hey peeps.
>
> Im involved in optimising a few C++ classes that interface with OpenGL
> I was wondering if the memory storage order of class members is
> standardised ?
>
> Will the array j from the derived class B always be stored before i from
the
> base class A ?
>
It depends on how it is inherited. Storage order with virtual inheritance
differs. It's usually safer, cleaner and more correct to avoid direct memory
access, and use inlined accessor functions. In your example, you could
define operator[] if you really need to access a class as if it were an
array.
Even if the classes aren't currently using any elaborate inheritence
mechanisms right now, that doesn't mean that they won't in the future.
E.g.
class A
{
int a;
};
class B : public class A
{
int b;
};
class C
{
int c;
}
what now?
class D : public class C, public class B
{
double d;
};
** or **
class D : public class B, public class C
{
double d;
};
I am assuming that your classes are really doing more than storing data. If
you are inheriting, what do you do about your vtable? If you don't declare
your destructors virtual, your instances will not be properly destroyed.
what happens if an instance of class D is referred to as a class A with C
members at the front? Your old code behaves unexpectedly simply because
someone uses a feature of the language to extend your old classes.
Instead, try:
class A
{
public:
A();
virtual ~A();
int operator[] (const int index) const;
private:
int *a;
int allocatedSize;
};
inline int A::operator[](const int index) const
{
assert(index < allocatedSize );
return a[index];
}
now, this would work no matter what the inheritence mechanism is. You will
always access A's members properly and even be able to validate your
accessors at runtime in debug mode.
void foo()
{
D d;
int j = d[3];
}
If you are concerned about performance, try testing the direct memory access
method vs using safer accessors. I've found that even for 3D rendering, the
cost is negligable compared to other operations (matrix operations, bus
transfer of texture and polygon data, etc..)
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Gaurav Sareen" <albelakela@hotmail.com>
Date: 27 Aug 2001 14:55:43 GMT Raw View
> Im involved in optimising a few C++ classes that interface with OpenGL
> I was wondering if the memory storage order of class members is
> standardised ?
No its not. Its dependent on the compiler. Typically the base class part is
stored right before the derived class part in order to make the common casts
to base efficient, just like C:
Base* b;
Derived* d = new Derived;
b = d; //This operation is just assigning one register to another.
However C++ language features ( virtual functions, virtual inheritance and
multiple inheritance) are typically implemented in different ways by diff
compilers. If you are going to use one particular version of one particular
compiler on one particular platform, perhaps you can get by by some
hardcoded magic, which is not recommended.
This IMO is one of the big reasons why java can be "safer" than C++ is that
the runtime layout of the classes is fixed.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Jack Klein <jackklein@spamcop.net>
Date: 28 Aug 2001 15:36:57 GMT Raw View
On 25 Aug 2001 23:50:42 GMT, "Fray Bentos"
<LOVELYSPAMfraybentos@wonderfulspamphreaker.net> wrote in
comp.lang.c++.moderated:
>
> Hey peeps.
>
> Im involved in optimising a few C++ classes that interface with OpenGL
> I was wondering if the memory storage order of class members is
> standardised ?
>
> Will the array j from the derived class B always be stored before i from the
> base class A ?
Your own code, undefined as it is, shows the array of ints in class A
being stored _before_ that from class B, not after.
> ------------------------8<---------------------
> #include <iostream>
>
> class A
> {
> public:
> int i[4];
>
> A(int a, int b, int c, int d)
> {
> i[0] = a*10 ; i[1] = b*10;
> i[2] = c*10 ; i[3] = d*10;
> }
> };
>
> class B : public A
> {
> public:
> int j[4];
>
> B(int a, int b, int c, int d) : A(a, b, c, d)
> {
> j[0] = a; j[1] = b;
> j[2] = c; j[3] = d;
> }
> };
>
> main()
I had to change this to a legal "int main()" to get this to compile
with my "better" compiler in strictly conforming mode.
> {
> B b(1, 2, 3, 4);
> int *ptr_b = reinterpret_cast<int*>(&b);
>
> for(int i=0; i<sizeof(b) / sizeof(int); i++)
> std::cout << ptr_b[i] << std::endl;
> }
> ------------------------8<---------------------
> output:
> 10
> 20
> 30
> 40
> 1
> 2
> 3
> 4
>
> Thanks
A base class appears before any of the additional data items added in
a derived class in a case like this. Otherwise it would not be
possible for a pointer to a base class to point to a derived class
object. The first sizeof(base class) bytes of the derived class must
be the instance of the base class in the derived class.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]