By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,502 Members | 1,620 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,502 IT Pros & Developers. It's quick & easy.

deriving from class in anonymous namespace

P: n/a
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.
Nov 7 '08 #1
Share this Question
Share on Google+
3 Replies


P: n/a
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.
Nov 7 '08 #2

P: n/a
On Nov 7, 4:52 pm, Al Grant <algr...@myrealbox.comwrote:
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:ja*********@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

Nov 7 '08 #3

P: n/a
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.
Nov 7 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.