using a class in an unnamed namespace as friend

Discussion in 'C++' started by marco_segurini, Jun 15, 2004.

  1. Hi,

    the following test program shows a solution to a problem I have had.

    Now, this test program is compiled and linked by VS2003 and g++
    while Comeau-on-line-compiler fails with this messages:

    "ComeauTest.c", line 21: error: constant "COuter::ID" is inaccessible
    int i = COuter::ID;
    ^
    ....some warning

    1 error detected in the compilation of "ComeauTest.c".

    who is wrong?

    many thanks.
    Marco.

    //sample begin
    namespace
    {
    class CInner;
    }

    class COuter
    {
    friend class CInner;

    enum { ID = 5 };
    };

    namespace
    {

    class CInner
    {
    public:
    CInner()
    {
    int i = COuter::ID;
    }
    };

    } //!namespace

    int main()
    {
    return 0;
    }
    marco_segurini, Jun 15, 2004
    #1
    1. Advertising

  2. marco_segurini wrote in
    news: in comp.lang.c++:

    > Hi,
    >
    > the following test program shows a solution to a problem I have had.
    >
    > Now, this test program is compiled and linked by VS2003 and g++
    > while Comeau-on-line-compiler fails with this messages:
    >
    > "ComeauTest.c", line 21: error: constant "COuter::ID" is inaccessible
    > int i = COuter::ID;
    > ^
    > ...some warning


    It would be unusual for Comeau/EDG to be wrong.

    >
    > 1 error detected in the compilation of "ComeauTest.c".
    >
    > who is wrong?


    VC++ and g++

    >


    > //sample begin
    > namespace
    > {
    > class CInner;
    > }
    >
    > class COuter
    > {
    > friend class CInner;
    >
    > enum { ID = 5 };
    > };


    Every things fine so far.

    >
    > namespace
    > {
    >


    Ouch - This isn't the *same* nameless namespace defined above,
    its a brand new one.

    > class CInner
    > {


    Double Ouch - Not the the same CInner, this one
    *isn't* a friend to COuter.

    > public:
    > CInner()
    > {
    > int i = COuter::ID;
    > }
    > };
    >
    > } //!namespace
    >
    > int main()
    > {
    > return 0;
    > }
    >


    In short you can't pre-*declare* anonymous things.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Jun 15, 2004
    #2
    1. Advertising

  3. marco_segurini

    tom_usenet Guest

    On 15 Jun 2004 19:25:38 GMT, Rob Williscroft <>
    wrote:

    >>
    >> namespace
    >> {
    >>

    >
    > Ouch - This isn't the *same* nameless namespace defined above,
    > its a brand new one.


    Are you sure? My reading of 7.3.1.1/1 suggests there is only one
    anonymous namespace name per translation unit. e.g. the OPs code
    should be "translated" to:

    //sample begin
    namespace unique
    {
    }
    using namespace unique;
    namespace unique
    {
    class CInner;
    }

    class COuter
    {
    friend class CInner;

    enum { ID = 5 };
    };

    namespace unique
    {

    class CInner
    {
    public:
    CInner()
    {
    int i = COuter::ID;
    }
    };

    } //!namespace

    int main()
    {
    return 0;
    }

    Interestingly, Comeau fails to compile the above too, and I think this
    is an EDG bug (that also causes the failure of the original code). The
    friend declaration in COuter should find unique::CInner according to
    the name lookup rules for elaborated-type-specifiers. However, Comeau
    considers the friend declaration to refer to ::CInner. My analysis may
    be flawed of course...

    >In short you can't pre-*declare* anonymous things.


    But you can according to Comeau. e.g.

    namespace
    {
    extern int i;
    }

    int main()
    {
    i = 10; //expect linker error if you can't
    }

    namespace
    {
    int i = 1;
    }

    Tom
    --
    C++ FAQ: http://www.parashift.com/c -faq-lite/
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    tom_usenet, Jun 16, 2004
    #3
  4. tom_usenet wrote in news:eek: in
    comp.lang.c++:

    >> Ouch - This isn't the *same* nameless namespace defined above,
    >> its a brand new one.

    >
    > Are you sure?


    I was, but not any more.

    > My reading of 7.3.1.1/1 suggests there is only one
    > anonymous namespace name per translation unit.
    >


    I miss-remembered the conclusion of a thread on comp.std.c++.
    I should have checked the standard myself of course.

    Thanks for the correction.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Jun 16, 2004
    #4
  5. tom_usenet wrote in news:eek: in
    comp.lang.c++:

    > //sample begin
    > namespace unique
    > {
    > }
    > using namespace unique;
    > namespace unique
    > {
    > class CInner;
    > }
    >
    > class COuter
    > {
    > friend class CInner;
    >
    > enum { ID = 5 };
    > };
    >
    > namespace unique
    > {
    >
    > class CInner
    > {
    > public:
    > CInner()
    > {
    > int i = COuter::ID;
    > }
    > };
    >
    > } //!namespace
    >
    > int main()
    > {
    > return 0;
    > }
    >
    > Interestingly, Comeau fails to compile the above too, and I think this
    > is an EDG bug (that also causes the failure of the original code). The
    > friend declaration in COuter should find unique::CInner according to
    > the name lookup rules for elaborated-type-specifiers. However, Comeau
    > considers the friend declaration to refer to ::CInner. My analysis may
    > be flawed of course...
    >


    Seems right. Though ::CInner should refer to unique::CInner in
    any case, so the friend declaration is unconditionaly inserting
    a declaration for class CInner into ::.

    The thread ( http://tinyurl.com/26dqo ) that I miss-remembered
    contains this workaround (http://tinyurl.com/2ams9 ):

    //sample begin
    #define unique
    //namespace unique {} using namespace unique;
    namespace unique
    {
    namespace foo
    {
    class CInner;
    }
    }

    class COuter
    {
    friend class foo::CInner;

    /* friend class ::CInner; doesn't work.
    g++ 3.4 and VC++ 7.1 accept it.
    */
    enum { ID = 5 };
    };

    namespace unique
    {
    namespace foo
    {
    class CInner
    {
    public:
    CInner()
    {
    int i = COuter::ID;
    }
    };
    }
    } //!namespace

    int main()
    {
    return 0;
    }

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Jun 16, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Razmig K
    Replies:
    3
    Views:
    681
    John L Fjellstad
    Sep 5, 2003
  2. marco_segurini

    unnamed namespace and friend

    marco_segurini, Feb 3, 2005, in forum: C++
    Replies:
    1
    Views:
    352
    msalters
    Feb 3, 2005
  3. Ivan Mascovich

    friend and unnamed namespace

    Ivan Mascovich, Mar 2, 2006, in forum: C++
    Replies:
    9
    Views:
    517
    Victor Bazarov
    Mar 3, 2006
  4. John Ratliff

    unnamed namespace and friend method

    John Ratliff, Feb 6, 2008, in forum: C++
    Replies:
    9
    Views:
    2,442
    Alf P. Steinbach
    Feb 8, 2008
  5. Niels Dekker - no reply address

    Using-declaration or using-directive inside unnamed-namespace?

    Niels Dekker - no reply address, Apr 27, 2010, in forum: C++
    Replies:
    1
    Views:
    585
    Niels Dekker - no reply address
    Apr 27, 2010
Loading...

Share This Page