deriving from class in anonymous namespace

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Al Grant

    #1

    deriving from class in anonymous namespace

    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.
  • Noah Roberts

    #2
    Re: deriving from class in anonymous namespace

    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.

    Comment

    • James Kanze

      #3
      Re: deriving from class in anonymous namespace

      On Nov 7, 4:52 pm, Al Grant <algr...@myreal box.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:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      • Juha Nieminen

        #4
        Re: deriving from class in anonymous namespace

        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.

        Comment

        Working...