[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

deriving from class in anonymous namespace

Al Grant

11/7/2008 3:53:00 PM

Consider two translation units, (1):

namespace { struct S { }; }
struct D: S { virtual int f(void); };

and (2):

#include <typeinfo>
struct D;
char const *f(D *p) { return typeid(p).name(); }

Does 'D' name the same type in (1) and (2)? The RTTI for
D* will reference an RTTI definition for D. Every ABI I've seen
will give D (and its RTTI) a well-defined name (e.g. _ZTI1D in
gABI), allowing external linkage to work here. But does the
standard guarantee that?

There's no ODR violation here, though a second definition of D
would presumably violate the ODR.

GCC 4.2 warns about deriving from a class in an anonymous
namespace, as if it was something to be ashamed of.
VC++ and Comeau don't warn.
3 Answers

john

11/7/2008 4:40:00 PM

0

Al Grant wrote:

> GCC 4.2 warns about deriving from a class in an anonymous
> namespace, as if it was something to be ashamed of.
> VC++ and Comeau don't warn.

Personally, I'd say GCC is correct to do so. What you are doing here is
publicly deriving from a private type. This makes no semantic sense.
Public inheritance is meant to be an "is-a" relationship and so what
you've done is claim D "is-a" private object, yet you're attempting to
expose it publicly.

You could improve the situation by using private inheritance. It is, it
seems to me, the only appropriate kind of inheritance for your situation.

James Kanze

11/7/2008 5:58:00 PM

0

On Nov 7, 4:52 pm, Al Grant <algr...@myrealbox.com> wrote:
> Consider two translation units, (1):

> namespace { struct S { }; }
> struct D: S { virtual int f(void); };

> and (2):

> #include <typeinfo>
> struct D;
> char const *f(D *p) { return typeid(p).name(); }

> Does 'D' name the same type in (1) and (2)? The RTTI for D*
> will reference an RTTI definition for D. Every ABI I've seen
> will give D (and its RTTI) a well-defined name (e.g. _ZTI1D in
> gABI), allowing external linkage to work here. But does the
> standard guarantee that?

> There's no ODR violation here, though a second definition of D
> would presumably violate the ODR.

> GCC 4.2 warns about deriving from a class in an anonymous
> namespace, as if it was something to be ashamed of. VC++ and
> Comeau don't warn.

It's a warning, not an error. In practice, either the
definition of D is in a header, in which case, including it in
two different translation units is undefined behavior, or it's
in a source file, in which case, D could also be in the unnamed
namespace. There are exceptions, though; I've done this a few
times when `D' was actually SomeClass::Impl and I wanted to
share the Impl (friend, second derived class, etc.) with other
classes in the source file, without making it publicly available
in the header. So all of the implementation was actually in the
class in the unnamed namespace, and SomeClass::Impl derived from
it. It's a fairly exceptional case, but IMHO reasonable enough
that the compiler shouldn't warn about it.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Juha Nieminen

11/7/2008 10:56:00 PM

0

Noah Roberts wrote:
> Al Grant wrote:
>
>> GCC 4.2 warns about deriving from a class in an anonymous
>> namespace, as if it was something to be ashamed of.
>> VC++ and Comeau don't warn.
>
> Personally, I'd say GCC is correct to do so. What you are doing here is
> publicly deriving from a private type. This makes no semantic sense.
> Public inheritance is meant to be an "is-a" relationship and so what
> you've done is claim D "is-a" private object, yet you're attempting to
> expose it publicly.
>
> You could improve the situation by using private inheritance. It is, it
> seems to me, the only appropriate kind of inheritance for your situation.

Why? The only way code outside that compilation unit can see the
derived class is as a forward-declared incomplete type. Thus all they
see is just a pointer to an incomplete type. They don't know anything
about it, and that's ok, because it is defined in terms of a private
base class definition.

It's not possible to bring the full declaration of that derived class
to other compilation units without also bringing the full declaration of
the base class as well.