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

using a class in an unnamed namespace as friend

P: n/a
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
Share this Question
Share on Google+
4 Replies


P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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.