470,590 Members | 2,546 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,590 developers. It's quick & easy.

using a class in an unnamed namespace as friend

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;
}
Jul 22 '05 #1
4 3610
marco_segurini wrote in
news:a3*************************@posting.google.co m 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/
Jul 22 '05 #2
On 15 Jun 2004 19:25:38 GMT, Rob Williscroft <rt*@freenet.co.uk>
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
Jul 22 '05 #3
tom_usenet wrote in news:o8********************************@4ax.com 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/
Jul 22 '05 #4
tom_usenet wrote in news:o8********************************@4ax.com 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/
Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by Sebastian Faust | last post: by
8 posts views Thread by Douglas | last post: by
16 posts views Thread by Eric | last post: by
1 post views Thread by Marco Jez | last post: by
3 posts views Thread by Sandy | last post: by
12 posts views Thread by Michael Maes | last post: by
30 posts views Thread by Pep | last post: by
3 posts views Thread by CrazyJohn | last post: by
3 posts views Thread by Al Grant | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.