Topic: C-struct inheritance portable?
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/05 Raw View
Paul D. DeRocco wrote:
>
> Steve Clamage wrote:
> >
> > Since
> > a POD-struct cannot have base classes, ClassCpp is not a POD-
> > struct, and layout compatibility with C is not guaranteed.
>
> Does it actually specify this in the draft standard? For instance:
There's no explicit statement that prohibits base classes in the
definition of POD structs (Section 9, paragraph 4)
| ... A POD-struct is an aggregate class
| that has no non-static data members of type pointer to member, non-
| POD-struct, non-POD-union (or array of such types) or reference, and
| has no user-defined copy assignment operator and no user-defined
| destructor.
Is such a prohibition implied elsewhere?
Incidentally, I thought POD-structs are prohibited from having virtual
members. If so, where does it say so? If not, how does the vtbl pointer
fit in?
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Netterdag <gabbe@teamcad.se>
Date: 1998/05/05 Raw View
James Kuyper wrote:
> There's no explicit statement that prohibits base classes in the
> definition of POD structs (Section 9, paragraph 4)
>
> | ... A POD-struct is an aggregate class
> | that has no non-static data members of type pointer to member, non-
> | POD-struct, non-POD-union (or array of such types) or reference, and
> | has no user-defined copy assignment operator and no user-defined
> | destructor.
>
> Is such a prohibition implied elsewhere?
> Incidentally, I thought POD-structs are prohibited from having virtual
> members. If so, where does it say so? If not, how does the vtbl pointer
> fit in?
This might be of interest.
8.5.1 Aggregates [dcl.init.aggr]
1 An aggregate is an array or a class (clause _class_) with no user-
declared constructors (_class.ctor_), no private or protected non-
static data members (clause _class.access_), no base classes (clause
_class.derived_), and no virtual functions (_class.virtual_).
Regards
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Martin Fabian <fabian@control.chalmers.se>
Date: 1998/04/29 Raw View
Is the following guaranteed to work?
extern "C" { // sort of
struct StructC
{ // some members ... };
void funcC(StructC *ptr)
{ // manipulating StructC's }
}
extern "C++" {
class ClassCpp : private StructC
{
// member functions only, no virtuals, no variables
}
void funcCpp(ClassCpp &ref)
{
funcC(&ref);
}
}
The question is really, is the layout of the ClassCpp (without vtbls or
added variables) guaranteed over all implementations to be exactly the
same as that of the C struct StructC?
--
Martin Fabian
-----------------------------------------------------------
email: fabian@control.chalmers.se | Control Engineering Laboratory
tel: +46 (0)31 772 37 16 | Chalmers University of Technology
fax: +46 (0)31 772 37 30 | S-412 96 Gothenburg
| Sweden
Homepage: http://www.control.chalmers.se/~fabian
------------------------------------------------------------------------
Everyone is talking about real-time, but how real is time, really?
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/04/29 Raw View
Martin Fabian <fabian@control.chalmers.se> writes:
>Is the following guaranteed to work?
>extern "C" { // sort of
> struct StructC
> { // some members ... };
> void funcC(StructC *ptr)
> { // manipulating StructC's }
>}
>extern "C++" {
> class ClassCpp : private StructC
> {
> // member functions only, no virtuals, no variables
> }
> void funcCpp(ClassCpp &ref)
> {
> funcC(&ref);
> }
>}
>The question is really, is the layout of the ClassCpp (without vtbls or
>added variables) guaranteed over all implementations to be exactly the
>same as that of the C struct StructC?
Your question at the end is not what you show in the code.
The C++ Standard requires that the layout of a POD-struct
be the same in C++ as in C (for some compatible C compiler on
the same system).
When you pass the address of a ClassCpp to funcC, the compiler
converts the pointer from ClassCpp* to StructC*. (There is no
implicit conversion to a private base class, but let's assume the
base class is public or the function is a friend or you used an
explicit cast.)
So the code will work if StructC is a POD-struct. If you copied
StructC from actual standard-conforming C code, it is a POD-struct.
In that case, it doesn't matter what ClassCpp looks like.
If you really want to know whether the size and layout of ClassCpp
is the same as StructC, the answer is "not necessarily". Since
a POD-struct cannot have base classes, ClassCpp is not a POD-
struct, and layout compatibility with C is not guaranteed. As a
practical matter, if ClassCPP has no virtual functions and no
new data members, its size and layout usually will be the same
as StructC. You just can't depend on it.
The detailed definition of POD-struct is in section 8.5.1 "Aggregates"
and section 9 "Classes" in the draft standard.
--
Steve Clamage, stephen.clamage@sun.com
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/04/30 Raw View
Patrick Hoonhout <hoonhout@artifice.com> writes:
>First of all there is no such thing as extern "C++", only extern "C".
>extern "C" means the linkage (calling convention) not the language.
The second statement is true. The first is false. Every C++ compiler
is required to support both 'extern "C"' and 'extern "C++"' linkage
specifiers.
You don't ordinarily need to use 'extern "C++"', but here is
an example:
extern "C" int f1();
extern "Fortran" int f2(); // a possible linkage
extern "C++" int f3();
First, the "C++" provides a visual clue. Second, suppose this code
is in a header that might get included like this:
extern "C" {
#include "head.h"
}
The seemingly-redundant linkage specifiers will ensure that
the declarations are handled properly. Linkage specifiers
nest, so that the innermost one overrides any outer specifiers.
>Rest assure, you can add virtual function and additional data members to
>ClassCpp. It will have no impact on the struct being passed to the C
>function. Virtual table information is stored at a negitive offset from
>the base object's address. Data members are just added after the struct.
Class layout varies widely among implementations. The C++ standard
assures nothing about the location of virtual table information,
and almost nothing about location of data members in a non-POD class.
--
Steve Clamage, stephen.clamage@sun.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Patrick Hoonhout <hoonhout@artifice.com>
Date: 1998/04/30 Raw View
Steve Clamage wrote:
> Patrick Hoonhout <hoonhout@artifice.com> writes:
>
> >First of all there is no such thing as extern "C++", only extern "C".
>
> >extern "C" means the linkage (calling convention) not the language.
>
> The second statement is true. The first is false. Every C++ compiler
> is required to support both 'extern "C"' and 'extern "C++"' linkage
> specifiers.
Thanks for the clarifcation. I did a search in the C++ pdf docs and
found extern "C++". I always thought extern "C++" was implicit when
using a C++ compiler (which it is.) And there is no real need for it,
except for, as you pointed out, clarification.
> >Rest assure, you can add virtual function and additional data members
> to
> >ClassCpp. It will have no impact on the struct being passed to the C
> >function. Virtual table information is stored at a negitive offset
> from
> >the base object's address. Data members are just added after the
> struct.
>
> Class layout varies widely among implementations. The C++ standard
> assures nothing about the location of virtual table information,
> and almost nothing about location of data members in a non-POD class.
Ok, so this compiler implementation issue. We should, however, be
guarantee that the "C" structure space will not be violated with C++
bagage when we cast to a base struct and pass it to a extern "C"
function.
Patrick.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Patrick Hoonhout <hoonhout@artifice.com>
Date: 1998/04/30 Raw View
Martin Fabian wrote:
> extern "C" { // sort of
> struct StructC
> { // some members ... };
>
> void funcC(StructC *ptr)
> { // manipulating StructC's }
> }
>
> extern "C++" {
> class ClassCpp : private StructC
> {
> }
> void funcCpp(ClassCpp &ref)
> {
> funcC(&ref);
> }
> }
> The question is really, is the layout of the ClassCpp (without vtbls
> or
> added variables) guaranteed over all implementations to be exactly the
>
> same as that of the C struct StructC?
First of all there is no such thing as extern "C++", only extern "C".
extern "C" means the linkage (calling convention) not the language.
Yes, you should have not difficulty passing a pointer to the base
struct. Provide, the struct is derived publicly and you don't attemp to
delete or free the struct. (The result is undefined.)
Rest assure, you can add virtual function and additional data members to
ClassCpp. It will have no impact on the struct being passed to the C
function. Virtual table information is stored at a negitive offset from
the base object's address. Data members are just added after the struct.
Patrick.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/05/01 Raw View
Martin Fabian wrote:
>
> Is the following guaranteed to work?
>
> extern "C" { // sort of
>
> struct StructC
> { // some members ... };
>
> void funcC(StructC *ptr)
> { // manipulating StructC's }
> }
>
> extern "C++" {
>
> class ClassCpp : private StructC
> {
> // member functions only, no virtuals, no variables
> }
>
> void funcCpp(ClassCpp &ref)
> {
> funcC(&ref);
> }
> }
> The question is really, is the layout of the ClassCpp (without vtbls
> or
> added variables) guaranteed over all implementations to be exactly the
> same as that of the C struct StructC?
The standard doesn't say anything about how the layout of an object is
affected by inheritance, so all bets are off. However, you are allowed
to add member functions to a POD, as long as they don't include a copy
assignment operator or a destructor (even non-virtual). You can
therefore probably rewrite the above code as a single C++ struct, and it
will still work.
In fact, I think the reason that copy assignments and destructors are
prohibited from PODs is merely to guarantee that PODs can be copied with
memcpy without violating their semantics. Thus, even if you do add a
non-virtual destructor, it shouldn't affect the layout, although that's
an inference, not a guarantee.
--
Ciao,
Paul
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/05/02 Raw View
Steve Clamage wrote:
>
> Since
> a POD-struct cannot have base classes, ClassCpp is not a POD-
> struct, and layout compatibility with C is not guaranteed.
Does it actually specify this in the draft standard? For instance:
struct point { int x; int y; };
struct rectangle: point { int w; int h; };
Is it technically true that rectangle isn't a POD structure?
--
Ciao,
Paul
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/05/02 Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>Steve Clamage wrote:
>>
>> Since
>> a POD-struct cannot have base classes, ClassCpp is not a POD-
>> struct, and layout compatibility with C is not guaranteed.
>Does it actually specify this in the draft standard? For instance:
> struct point { int x; int y; };
> struct rectangle: point { int w; int h; };
>Is it technically true that rectangle isn't a POD structure?
Yes. Since someone else asked what "POD" means, I might as well
quote from the draft standard. By the way, "POD" means
"Plain Old Data".
The purpose of defining a POD-class was to define a category of
structured type which was assuredly compatible with C.
Now Draft Standard clause 9, paragraph 4:
"A structure is a class defined with the class-key "struct"; its members
and base classes (clause 10) are public by default (clause 11). A union
is a class defined with the class-key "union"; its members are public by
default and it holds only one data member at a time (9.5). [Note:
aggregates of class type are described in 8.5.1. ] A POD-struct is an
aggregate class that has no non-static data members of type pointer to
member, non-POD-struct, non-POD-union (or array of such types) or
reference, and has no user-defined copy assignment operator and n
user-defined destructor. Similarly, a POD-union is an aggregate union
that has no non-static data members of type pointer to member,
non-POD-struct, non-POD-union (or array of such types) or reference,
and has no user-defined copy assignment operator and no user-defined
destructor. A POD class is a class that is either a POD-struct or a
POD-union."
Here's the definition of "aggregate" from section 8.5.1, paragraph 1:
"An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3)."
An aggregate can use brace-initialization, while a non-aggregate
cannot. A non-aggregate can be initialized only by default-
initialization or by a constructor. An aggregate can have C++
features that prevent it from being a POD.
A class with a base class is not an aggregate because the standard
places no requirements on the location of base-class vs derived-
class data (for example), and the implementation might choose to
add hidden fields to the derived class for its own use. Such
hidden fields might depend on the actions of a constructor, and
so brace-initialization is disallowed.
---
Steve Clamage, stephen.clamage@sun.com
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1998/05/02 Raw View
Patrick Hoonhout wrote:
>
>
> First of all there is no such thing as extern "C++", only extern "C".
The C++ standard requires compilers to recognize both extern "C" and
extern "C++". They're inverses:
extern "C"
{
void f(); // C-callable
extern "C++"
{
void g(); // not guaranteed to be C-callable
}
};
Vendors can add their own languages as well.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Mike Davies <mike_davies@noco.demon.co.uk>
Date: 1998/05/02 Raw View
In article <3548384B.C3C5CFA8@ix.netcom.com>, "Paul D. DeRocco"
<pderocco@ix.netcom.com> writes
>The standard doesn't say anything about how the layout of an object is
>affected by inheritance, so all bets are off. However, you are allowed
>to add member functions to a POD, as long as they don't include a copy
>assignment operator or a destructor (even non-virtual). You can
>therefore probably rewrite the above code as a single C++ struct, and it
>will still work.
Forgive me, what's a POD ?
--
Mike Davies
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]