473,467 Members | 1,410 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

friend and unnamed namespace

Previous posts (and compilers) confirm that

class X
{
friend void Y() ;
} ;

does not match

namespace
{
void y ()
{
}

}

Is there any way to declare the friend such that it will match a function
in an unnamed namespace --- OR does one simply have to do things the old
way with static?
Mar 2 '06 #1
9 5387
* Ivan Mascovich:
Previous posts (and compilers) confirm that

class X
{
friend void Y() ;
} ;

does not match

namespace
{
void y ()
{
}

}
Well, it can't, because Y and y are two different names.

But if you use the same function name (et cetera), then yes, there's no
way to forward-declare a function in an anonymous namespace outside of
that namespace, because each anonymous namespace is a different
namespace, and can't be referred to.

Is there any way to declare the friend such that it will match a function
in an unnamed namespace
Not in any useful way, no (if you have the anonyous namespace before the
class definition it rather defeats the purpose).

--- OR does one simply have to do things the old way with static?


static is good, whether you mean a namespace scope static function, or a
static member function; the first restricts access to this translation
unit, and the second can restrict access to this class.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 3 '06 #2
Ivan Mascovich wrote:
Previous posts (and compilers) confirm that

class X
{
friend void Y() ;
} ;

does not match

namespace
{
void y ()
{
}

}
First of all, 'Y' and 'y' are different names in C++.
Is there any way to declare the friend such that it will match a function
in an unnamed namespace --- OR does one simply have to do things the old
way with static?


There is no way. Take a look:
------------------------------------------
class A;
namespace NS {
int Y(A*);
}

using namespace NS;

int y = Y(0);

class A {
int a;
friend int NS::Y(A*); /////////// *****************
};

namespace NS {
int Y(A* pa) {
return pa->a;
}
}

int main() {
A a;
Y(&a);
}
-----------------------------------------

Imagine that 'NS' does not exist, but is replaced with some unique to your
translation unit identifier. That's what essentially happens when you
create an unnamed namespace. Now, notice that if you remove the 'NS::'
from the 'friend' declaration in 'class A', the friend declaration will
_introduce_ the name 'Y' into the _global_ namespace. Then the program
will be ill-formed due to two reasons: access to 'a' member in 'Y' is not
granted and in 'main' the call to 'Y' is ambiguous.

That's the problem with 'friend' declarations, not with unnamed namespaces
and the way to combat it would be either name your namespace and use the
name in the 'friend' as well, or (temporarily, until your compiler stops
supporting those) use 'static'. The use of 'static' for declaring any
functions you don't want other modules to see has been deprecated.

V
--
Please remove capital As from my address when replying by mail
Mar 3 '06 #3
Alf P. Steinbach wrote:
* Ivan Mascovich:
Previous posts (and compilers) confirm that

class X
{
friend void Y() ;
} ;

does not match

namespace
{
void y ()
{
}

}

Well, it can't, because Y and y are two different names.

But if you use the same function name (et cetera), then yes, there's no
way to forward-declare a function in an anonymous namespace outside of
that namespace, because each anonymous namespace is a different
namespace, and can't be referred to.


That's not true. You can forward-declare any function in an unnamed
namespace in the _same_ translation unit. The problem is that forward-
declaring it does not help.
Is there any way to declare the friend such that it will match a
function in an unnamed namespace

Not in any useful way, no (if you have the anonyous namespace before the
class definition it rather defeats the purpose).


No. The problem in the way 'friend' works, not in the way unnamed
namespaces work.
> --- OR does one simply have to do things the old way with static?


static is good, whether you mean a namespace scope static function, or a
static member function; the first restricts access to this translation
unit, and the second can restrict access to this class.


A static member of the same class has all access it needs, there is no
need to declare it a friend.

V
--
Please remove capital As from my address when replying by mail
Mar 3 '06 #4
* Victor Bazarov:
Alf P. Steinbach wrote:
* Ivan Mascovich:
Previous posts (and compilers) confirm that

class X
{
friend void Y() ;
} ;

does not match

namespace
{
void y ()
{
}

}

Well, it can't, because Y and y are two different names.

But if you use the same function name (et cetera), then yes, there's
no way to forward-declare a function in an anonymous namespace outside
of that namespace, because each anonymous namespace is a different
namespace, and can't be referred to.


That's not true. You can forward-declare any function in an unnamed
namespace in the _same_ translation unit.


In practice, with current compilers, that seems to be the case, yes.

However, the standard seems quite clear when it /syntactically/ reserves
the mechanism of namespace extension to named namespaces

And requires every anonymous namespace (not making any distiction
between "in the same translation unit" or otherwise) to behave as if it
had a globally unique name.

Which would make it different to declare a function in one anonymous
namespace and define it in another, even in the same translation unit.

Perhaps you could cite the relevant part of the standard that allows an
anonymous namespace to be extended (in the same translation unit)?

The problem is that forward- declaring it does not help.
Is there any way to declare the friend such that it will match a
function in an unnamed namespace

Not in any useful way, no (if you have the anonyous namespace before
the class definition it rather defeats the purpose).


No. The problem in the way 'friend' works, not in the way unnamed
namespaces work.


Again, that seems to be the case in practice, with current compilers.

However, again I'm afraid I must ask for language in the standard that
supports that view.

It may be that I'm blind on both eyes, but it may be that we're on the
trail of not just one but two different defects in the standard.

> --- OR does one simply have to do things the old way with static?


static is good, whether you mean a namespace scope static function, or
a static member function; the first restricts access to this
translation unit, and the second can restrict access to this class.


A static member of the same class has all access it needs, there is no
need to declare it a friend.


That's right, that's why the OP mentioned it as an alternative.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 3 '06 #5
Alf P. Steinbach wrote:
[..]
Perhaps you could cite the relevant part of the standard that allows
an anonymous namespace to be extended (in the same translation unit)?

I am not going to cite it. Open it on page 115 and read 7.3.1.1.
Pay special attention to the words "where _all_ occurrences..."
(emphasis mine).
[..]


V
--
Please remove capital As from my address when replying by mail
Mar 3 '06 #6
Alf P. Steinbach wrote:

However, the standard seems quite clear when it /syntactically/ reserves
the mechanism of namespace extension to named namespaces
Well, "reserves" is a bit strong. Yes, there are two grammar
productions, one for an unnamed-namespace-definition, and one for an
unnamed-namespace-extension. The obvious purpose of that distinction is
to be able to say that the name of an unnamed-namespace-extension must
have been the name in a prior unnamed-namespace-definition. I'd be leary
of reading more subtle implications into that.

And requires every anonymous namespace (not making any distiction
between "in the same translation unit" or otherwise) to behave as if it
had a globally unique name.


On the contrary: 7.3.1/1 says

An unnamed-namespace-definition behaves as if it
were replaced by

namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of 'unique' IN A
TRANSLATION UNIT are replaced by the same identifier
and this identifier differs from all other identifiers
in the entire program. [emphasis added]

Now, certainly, the following is valid:

namespace x { /* empty body */ } // definition
using namespace x;
namespace x { int i; } // extension

namespace x { /* empty body */ } // extension
using namespace x;
namespace x { int j; } // extension

and if you replace 'x' by 'unique' that's what you get from

namespace { int i; }
namespace { int j; }

--

Pete Becker
Roundhouse Consulting, Ltd.
Mar 3 '06 #7
* Victor Bazarov:
Alf P. Steinbach wrote:
[..]
Perhaps you could cite the relevant part of the standard that allows
an anonymous namespace to be extended (in the same translation unit)?


I am not going to cite it. Open it on page 115 and read 7.3.1.1.
Pay special attention to the words "where _all_ occurrences..."
(emphasis mine).


Yep, you're right about that.

That leaves the second part I addressed in that posting, your statement

"Now, notice that if you remove the 'NS::' from the 'friend'
declaration in 'class A', the friend declaration will _introduce_ the
name 'Y' into the _global_ namespace."

Yes, that's how current compilers behave, but finding that in the
standard is beyond me.

§3.3/4 says a friend declaration "may introduce a (possibly not visible)
name into an enclosing namespace".

§3.3.1/6 contrariwise says friend declarations "do not introduce new
names into [the nearest enclosing namespace]".

§7.3.1.2/3 is perhaps the one nearest to saying what you say (and
current compilers do), namely that

"If a friend declaration in a non-local class first declares a class
or function[note 83] the friend class or function is a member of the
innermost enclosing namespace."

where note 83 is "this implies that the name of the class or function is
unqualified".

A using-declaration is a declaration, so

using SomeNameSpace::foo;

should suffice as a pre-declaration of foo() in the namespace enclosing
the class -- but it does not, with current compilers.

§11.4/7, in the "Friends" section, requires that

"A name nominated by a friend declaration shall be accessible in the
scope of the class containing the friend declaration"

And there is no other requirement, as far as I can see.

Is there perhaps something I have overlooked?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 3 '06 #8
* Pete Becker:
where all occurrences of 'unique' IN A
TRANSLATION UNIT are replaced by the same identifier
and this identifier differs from all other identifiers
in the entire program. [emphasis added]


Yep, thanks!

I may have to invest in new glasses... ;-)

Perhaps there's something I likewise simply don't see (before it's
pointed out) regarding the effect of unqualified names in friend
function declarations; I'm aware of §7.3.1.2/3, but what I'm able to see
of it -- heh -- doesn't seem to preclude something like

namespace ANameSpace{ void x(); }
using ANameSpace::x; // If this isn't 'first declared', then
// a 'void x() {}' here should compile?

class Foo
{
friend void x();
};

with the definition of ANameSpace::x then having friendship status (yes,
I know that's not how current compilers work).

What I do see is that §11.4/7 requires that

"A name nominated by a friend declaration shall be accessible in the
scope of the class containing the friend declaration"

and 'void x()' is accessible, isn't it?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 3 '06 #9
Alf P. Steinbach wrote:
[..]
"Now, notice that if you remove the 'NS::' from the 'friend'
declaration in 'class A', the friend declaration will _introduce_ the
name 'Y' into the _global_ namespace."

Yes, that's how current compilers behave, but finding that in the
standard is beyond me.

§3.3/4 says a friend declaration "may introduce a (possibly not visible)
name into an enclosing namespace".

§3.3.1/6 contrariwise says friend declarations "do not introduce new
names into [the nearest enclosing namespace]".
That's in a "Note", which is non-normative.
§7.3.1.2/3 is perhaps the one nearest to saying what you say (and
current compilers do), namely that

"If a friend declaration in a non-local class first declares a class
or function[note 83] the friend class or function is a member of the
innermost enclosing namespace."

where note 83 is "this implies that the name of the class or function is
unqualified".

A using-declaration is a declaration, so

using SomeNameSpace::foo;

should suffice as a pre-declaration of foo() in the namespace enclosing
the class -- but it does not, with current compilers.
'using' declaration like that does not make 'foo' a _member_ [of the
global, I presume, namespace], it just makes it _resolvable_.
§11.4/7, in the "Friends" section, requires that

"A name nominated by a friend declaration shall be accessible in the
scope of the class containing the friend declaration"

And there is no other requirement, as far as I can see.

Is there perhaps something I have overlooked?


Maybe. AFA I'm concerned, this is one of the most convoluted and unclear
parts of the language, which suggests that declaring anything as 'friend'
should be generally avoided.

V
--
Please remove capital As from my address when replying by mail
Mar 3 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

53
by: Oliver Fromme | last post by:
Hi, I'm trying to write a Python function that parses an expression and builds a function tree from it (recursively). During parsing, lambda functions for the the terms and sub-expressions...
21
by: Sebastian Faust | last post by:
Hi, is a construction like the following possible: template<class view_model> class template_clase { protected: template_clase() {} virtual ~template_clase() {}
4
by: marco_segurini | last post by:
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:...
1
by: marco_segurini | last post by:
Hi, I like to know if this code is legal: namespace { void unnamed_ns(){} } class test
1
by: Marco Jez | last post by:
What are the requirements imposed by the Standard on unnamed namespaces? I mean, is the hidden name guaranteed to be unique across multiple translation units, or only within the declaring...
3
by: Sandy | last post by:
Hi, I have two files as folllows file1.cpp #include<iostream> using namespace std; namespace { void show(); void fun() { cout<<"fun called\n"; } }
2
by: dioscuroi | last post by:
Is there any difference between declaring in unnamed namespace and i global namespace? I can't recognize this p.s: Have a nice day ^_________ -
1
by: vsgdp | last post by:
I just want to clarify: Say I have a helper class that is only used in one translation file (e.g., a predicate class). I don't want the name of this class to conflict with other class names in...
3
by: CrazyJohn | last post by:
Hi guys, This is my first time posting question here, if I break any rules, please kindly point out. And I'm really glad to be a part of this community. Here is my question, Our lecturer...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.