473,399 Members | 3,302 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

About friend declaration

I find friend declaration just very tricky. I tried the following
examples on both MingW(gcc 3.4.2) and VC++ 2005. The results are
surprising.

Example1:
namespace ns1
{
class Test
{
friend void func()
{
printf("func in %s\n", __FILE__);
}
};
}

int main()
{
ns1::func();
}

---End Example1---
gcc: compiles and works
VC++: compile error: 'func': candidate function(s) not accessible

Example2:
-file1.cpp
namespace ns1
{
class Test
{
friend void func();
};
}

int main()
{
ns1::func2("abc");
}

-file2.cpp
namespace ns1
{
void func()
{
printf("func in %s\n", __FILE__);
}
}
---end Example2---
gcc: compiles and works
VC++: compiles and works

I'm rather confused. Does a friend function declaration make it as if
it's also declared in the enclosing namespace? At least in example2,
it seems to be so.

What about Example1? What is the right behavior?
Jun 27 '08 #1
6 3140
WaterWalk wrote:
I find friend declaration just very tricky. I tried the following
examples on both MingW(gcc 3.4.2) and VC++ 2005. The results are
surprising.

Example1:
namespace ns1
{
class Test
{
friend void func()
{
printf("func in %s\n", __FILE__);
}
};
}

int main()
{
ns1::func();
}

---End Example1---
gcc: compiles and works
It does not on GCC 4.1.2.

error: 'func' is not a member of 'ns1'
VC++: compile error: 'func': candidate function(s) not accessible

Example2:
-file1.cpp
namespace ns1
{
class Test
{
friend void func();
};
}

int main()
{
ns1::func2("abc");
}
How does "func2" enter the picture here? This cannot compile as it is,
so you obviously did not post the actual code.
--
Christian Hackl
Jun 27 '08 #2
On May 24, 3:44 pm, WaterWalk <toolmas...@163.comwrote:
I find friend declaration just very tricky. I tried the
following examples on both MingW(gcc 3.4.2) and VC++ 2005. The
results are surprising.
Example1:
namespace ns1
{
class Test
{
friend void func()
{
printf("func in %s\n", __FILE__);
}
Note that although the function you define is ns1::func, the
declaration for this function is only visible in Test. Since
the function has no parameters, ADL won't enter into effect
either.
};
}
int main()
{
ns1::func();
The name shouldn't be visible here.
}
---End Example1---
gcc: compiles and works
Not with the version I have.
VC++: compile error: 'func': candidate function(s) not accessible
"not visible" would be a better message. Or simply that it
cannot find the function.

Earlier (pre-standard) versions of C++ injected the name of a
friend into the surrounding scope, so some compilers may still
do this for reasons of backwards compatibility.
Example2:
-file1.cpp
namespace ns1
{
class Test
{
friend void func();
};

}
int main()
{
ns1::func2("abc");
I presume you mean ns1::func.
}
-file2.cpp
namespace ns1
{
void func()
{
printf("func in %s\n", __FILE__);
}
}
---end Example2---
gcc: compiles and works
VC++: compiles and works
This should have the same problem as the above. There is no
declaration of ns1::func visible when you compile main, so the
code shouldn't compile. (Again, the g++ I have here doesn't
compile it. The error message is:
names.cc:20: error: ‘func’ is not a member of ‘ns1’
Not perfect, either: `func' cannot be found in `ns1' would be
better.)
I'm rather confused. Does a friend function declaration make
it as if it's also declared in the enclosing namespace?
No, but it did in pre-standard C++. (More correctly, it
injected the name into file scope---there weren't namespaces ini
pre-standard C++, so there was no namespace scope.)

I forget the reason why the committee changed this. (I've been
told at least a half dozen times. Each time, I recognize that
it is valid, but end up forgetting exactly what it was.) There
was discussion concerning the possibility of breaking existing
code, but in practice, no one could figure out a possible use
for a friend function that didn't have an argument which
depended on the class it was a friend of, and with such an
argument, ADL finds the function, even if the declaration isn't
visible.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #3
On May 25, 1:26 am, James Kanze <james.ka...@gmail.comwrote:
On May 24, 3:44 pm, WaterWalk <toolmas...@163.comwrote:
I find friend declaration just very tricky. I tried the
following examples on both MingW(gcc 3.4.2) and VC++ 2005. The
results are surprising.
Example1:
namespace ns1
{
class Test
{
friend void func()
{
printf("func in %s\n", __FILE__);
}

Note that although the function you define is ns1::func, the
declaration for this function is only visible in Test. Since
the function has no parameters, ADL won't enter into effect
either.
};
}
int main()
{
ns1::func();

The name shouldn't be visible here.
}
---End Example1---
gcc: compiles and works

Not with the version I have.
VC++: compile error: 'func': candidate function(s) not accessible

"not visible" would be a better message. Or simply that it
cannot find the function.

Earlier (pre-standard) versions of C++ injected the name of a
friend into the surrounding scope, so some compilers may still
do this for reasons of backwards compatibility.
Example2:
-file1.cpp
namespace ns1
{
class Test
{
friend void func();
};
}
int main()
{
ns1::func2("abc");

I presume you mean ns1::func.
}
-file2.cpp
namespace ns1
{
void func()
{
printf("func in %s\n", __FILE__);
}
}
---end Example2---
gcc: compiles and works
VC++: compiles and works

This should have the same problem as the above. There is no
declaration of ns1::func visible when you compile main, so the
code shouldn't compile. (Again, the g++ I have here doesn't
compile it. The error message is:
names.cc:20: error: ‘func’ is not a member of ‘ns1’
Not perfect, either: `func' cannot be found in `ns1' would be
better.)
I'm rather confused. Does a friend function declaration make
it as if it's also declared in the enclosing namespace?

No, but it did in pre-standard C++. (More correctly, it
injected the name into file scope---there weren't namespaces ini
pre-standard C++, so there was no namespace scope.)

I forget the reason why the committee changed this. (I've been
told at least a half dozen times. Each time, I recognize that
it is valid, but end up forgetting exactly what it was.) There
was discussion concerning the possibility of breaking existing
code, but in practice, no one could figure out a possible use
for a friend function that didn't have an argument which
depended on the class it was a friend of, and with such an
argument, ADL finds the function, even if the declaration isn't
visible.
Thanks for this information. But at the same time, I find some curious
statements in the c++ standard and some books:
c++ standard 3.3/4
In particular, elaborated-type-specifiers
(3.3.1) and friend declarations (11.4) may introduce a (possibly not
visible) name into an enclosing namespace;
these restrictions apply to that region.

c++ standard 3.3.1/6
[Note: friend declarations refer to functions or classes that are
members of the nearest enclosing namespace,
but they do not introduce new names into that namespace (7.3.1.2).

To me, they look to say the opposite things. What's more:
C++ Primer, 4th edition, in Chapter 12.5
A friend declaration introduces the named class or nonmember function
into the surrounding scope.

In the same chapter, an example is given:
class X
{
friend class Y;
friend void f();
};

class Z
{
Y *ymem; //ok, declaration for class Y introduced by friend in X
void g() {return ::f();} //ok, declaration of f introduced by X
};

Another source of confusion is how a friend declaration affects name
lookup in the class granting friendship? For example:
class X
{
public:
void show();
Y *py; // is Y visible ?
friend claxx Y
friend void f();
};

void X::show()
{
f(); //is f visible?
}
In X's member function definitions, will f be visible? In X's member
declarations, will Y be visible?

I searched in the standard, but didn't find clues in it's chapters
about name lookup(in 3.4).
Jun 27 '08 #4
On May 25, 2:32 pm, "Alf P. Steinbach" <al...@start.nowrote:
* WaterWalk:
On May 25, 1:26 am, James Kanze <james.ka...@gmail.comwrote:
On May 24, 3:44 pm, WaterWalk <toolmas...@163.comwrote:
>I find friend declaration just very tricky. I tried the
following examples on both MingW(gcc 3.4.2) and VC++ 2005. The
results are surprising.
Example1:
namespace ns1
{
class Test
{
friend void func()
{
printf("func in %s\n", __FILE__);
}
Note that although the function you define is ns1::func, the
declaration for this function is only visible in Test. Since
the function has no parameters, ADL won't enter into effect
either.
> };
}
int main()
{
ns1::func();
The name shouldn't be visible here.
>}
---End Example1---
gcc: compiles and works
Not with the version I have.
>VC++: compile error: 'func': candidate function(s) not accessible
"not visible" would be a better message. Or simply that it
cannot find the function.
Earlier (pre-standard) versions of C++ injected the name of a
friend into the surrounding scope, so some compilers may still
do this for reasons of backwards compatibility.
>Example2:
-file1.cpp
namespace ns1
{
class Test
{
friend void func();
};
}
int main()
{
ns1::func2("abc");
I presume you mean ns1::func.
>}
-file2.cpp
namespace ns1
{
void func()
{
printf("func in %s\n", __FILE__);
}
}
---end Example2---
gcc: compiles and works
VC++: compiles and works
This should have the same problem as the above. There is no
declaration of ns1::func visible when you compile main, so the
code shouldn't compile. (Again, the g++ I have here doesn't
compile it. The error message is:
names.cc:20: error: ‘func’ is not a member of ‘ns1’
Not perfect, either: `func' cannot be found in `ns1' would be
better.)
>I'm rather confused. Does a friend function declaration make
it as if it's also declared in the enclosing namespace?
No, but it did in pre-standard C++. (More correctly, it
injected the name into file scope---there weren't namespaces ini
pre-standard C++, so there was no namespace scope.)
I forget the reason why the committee changed this. (I've been
told at least a half dozen times. Each time, I recognize that
it is valid, but end up forgetting exactly what it was.) There
was discussion concerning the possibility of breaking existing
code, but in practice, no one could figure out a possible use
for a friend function that didn't have an argument which
depended on the class it was a friend of, and with such an
argument, ADL finds the function, even if the declaration isn't
visible.
Thanks for this information. But at the same time, I find some curious
statements in the c++ standard and some books:
c++ standard 3.3/4
In particular, elaborated-type-specifiers
(3.3.1) and friend declarations (11.4) may introduce a (possibly not
visible) name into an enclosing namespace;
these restrictions apply to that region.
c++ standard 3.3.1/6
[Note: friend declarations refer to functions or classes that are
members of the nearest enclosing namespace,
but they do not introduce new names into that namespace (7.3.1.2).

Yeah, it's inconsistent.

As far as I can recall there isn't an active issue on it, either.

There should be.

Cheers, & hth.,
I hope so. But maybe I misunderstand some statements in the C++
standard. Not sure.
Jun 27 '08 #5
On May 25, 8:32 am, "Alf P. Steinbach" <al...@start.nowrote:
* WaterWalk:
[...]
Thanks for this information. But at the same time, I find some curious
statements in the c++ standard and some books:
c++ standard 3.3/4
In particular, elaborated-type-specifiers
(3.3.1) and friend declarations (11.4) may introduce a (possibly not
visible) name into an enclosing namespace;
these restrictions apply to that region.
c++ standard 3.3.1/6
[Note: friend declarations refer to functions or classes that are
members of the nearest enclosing namespace,
but they do not introduce new names into that namespace (7.3.1.2).
Yeah, it's inconsistent.
As far as I can recall there isn't an active issue on it, either.
There should be.
Well, both quotes are from non-normative notes; there's no
ambiguity in the normative requirements. But the first one
should definitely be either corrected or dropped. And the
second one seems a bit ambiguous as well to me: a friend
declaration can introduce a new name into a namespace; it just
doesn't make it visible. (But I think that there is a more
general problem of vocabulary here.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #6
On May 27, 10:18 am, James Kanze <james.ka...@gmail.comwrote:
On May 25, 8:32 am, "Alf P. Steinbach" <al...@start.nowrote:
* WaterWalk:
[...]
Thanks for this information. But at the same time, I find some curious
statements in the c++ standard and some books:
c++ standard 3.3/4
In particular, elaborated-type-specifiers
(3.3.1) and friend declarations (11.4) may introduce a (possibly not
visible) name into an enclosing namespace;
these restrictions apply to that region.
c++ standard 3.3.1/6
[Note: friend declarations refer to functions or classes that are
members of the nearest enclosing namespace,
but they do not introduce new names into that namespace (7.3.1.2).
Yeah, it's inconsistent.
As far as I can recall there isn't an active issue on it, either.
There should be.
Well, both quotes are from non-normative notes; there's no
ambiguity in the normative requirements. But the first one
should definitely be either corrected or dropped. And the
second one seems a bit ambiguous as well to me: a friend
declaration can introduce a new name into a namespace; it just
doesn't make it visible. (But I think that there is a more
general problem of vocabulary here.)
While preparing to write up a request for an editorial change
here, I reread the quoted passages in context, and realize that
in context, they are quite clear: the friend declaration
introduces the name into the enclosing namespace, but does not
make it visible there.

This also clears up the question of vocabulary: when the
standard says that a name is "in" a given namespace, that means
that the name (or the entity designated by the name) is a member
of that namespace. When it speaks of scope, it uses the word
visibility or visible. Thus, in the initial example:

namespace NS {
class Foo {
friend void f() ;
} ;
}

The friend declaration introduces the name f into the namespace
NS, but does not make it visible (in scope) in the namespace NS.
In other words, the declaration declares a fully qualified name
::NS::f(), but the declaration is (visible) in the scope of
::NS::Foo.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #7

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

Similar topics

2
by: Christophe Barbe | last post by:
I am not clear about friend functions of a template class. GCC (3.3.2) wants me to add <> after the friend function names in the class declaration and VisualC++ doesn't like that. template...
5
by: Trevor Lango | last post by:
What is the appropriate syntax for placing a friend function that includes as one of it's parameters a pointer to the class object itself within the template class? I have the following: ...
2
by: Ruben Campos | last post by:
I have a problem with a template function that is declared as a friend of a template class. I'll first show the exact problem with source code: // MyClass.hpp template <typename T> class...
9
by: Neelesh | last post by:
I was reading TC++PL (Chapter 11, section 11.5.1 "finding friends") where it is mentioned that What I observe is a bit different - it is fine that there is an error for Xform, but the reason...
9
by: Ivan Mascovich | last post by:
Previous posts (and compilers) confirm that class X { friend void Y() ; } ; does not match namespace
5
by: Steven T. Hatton | last post by:
This note appears in the discussion of name hiding and uniqueness: §3.3 #4 This note is item #6 in the discussion of "Point of declaration" §3.3.1 #6 What exactly do these statements mean?...
75
by: Steven T. Hatton | last post by:
No, this is not a troll, and I am not promoting Java, C-flat, D, APL, Bash, Mathematica, SML, or LISP. A college teacher recently posted to this newsgroup regarding her observation that there has...
4
by: fdmfdmfdm | last post by:
I have the following code: #include <iostream> #include <cstdlib> #include <cassert> using namespace std; template <class T> class Stack{ public: enum{DefaultStack = 10, EmptyStack = -1};
4
by: StephQ | last post by:
According to: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.4 , if my understanding is correct, in template<typename T> class Foo { friend void func (const Foo<T>& foo); }; ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...

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.