Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

friend function defined in the class

4 views
Skip to first unread message

Lin Jen-Shin

unread,
Aug 2, 2006, 12:49:30 PM8/2/06
to
I don't know whether the code is in standard or not,
but somehow it's compiled in compilers I've tried.

class Dummy{
friend void hi(){ std::cout << "hi" << std::endl; }
};

"hi" is a namespace level function, not a method of Dummy.

Consider codes below:

class Dummy{
friend void hi(){ std::cout << "hi" << std::endl; }
friend void hello(){ ::hi(); }
};

I've tried 3 compilers to compile above code, which are

a) g++ 3.4.5
b) VC++ 7.1
c) Comeau C/C++ 4.3.3

with all warning on and strict mode in standard.

g++ compiled fine, while the others failed.

VC++ 7.1 said:

error C3767: 'hi' matching function is not accessible
could be the friend function at '[snip]' : 'hi'
[may be found via argument-dependent lookup]

Comeau C/C++ 4.3.3 said:

error: the global scope has no "hi"
friend void hello(){ ::hi(); }

If I didn't know things wrong, which VC++ 7.1 said "argument-dependent
lookup"
was also called "Koneig Lookup", which I got from
http://en.wikipedia.org/wiki/Koenig_lookup.
And it is in standard, right?

However, what makes me wonder most is that if I add codes below front
of friend:

extern void hi();

Then VC++ 7.1 and Comeau C/C++ 4.3.3 compiled fine, linked fine.

If I provide another definition of ::hi():

void hi(){}

then all of the compilers complained about "multi-definition" in
compile time.

Moreover, if I didn't use strict mode in Comeau C/C++ 4.3.3, then it
compiled
fine just as g++ 3.4.5 did, no need to provide additional forward
declaration.

So, who is right and who is wrong?
What's standard said about this?

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Kristof Zelechovski

unread,
Aug 3, 2006, 11:56:09 AM8/3/06
to

Uzytkownik "Lin Jen-Shin" <god...@gmail.com> napisal w wiadomosci
news:1154531745.6...@m73g2000cwd.googlegroups.com...

Right.

> However, what makes me wonder most is that if I add codes below front
> of friend:
>
> extern void hi();
>
> Then VC++ 7.1 and Comeau C/C++ 4.3.3 compiled fine, linked fine.

Because you unhid the function. When the friend function is declared within
the class, it is inaccessible outside until it is also declared outside.

>
> If I provide another definition of ::hi():
>
> void hi(){}
>
> then all of the compilers complained about "multi-definition" in
> compile time.
>

By ODR.

> Moreover, if I didn't use strict mode in Comeau C/C++ 4.3.3, then it
> compiled
> fine just as g++ 3.4.5 did, no need to provide additional forward
> declaration.
>

Compilers are free to compile ill-formed code. However, such code is
unnecessarily unportable.

> So, who is right and who is wrong?

By the rule I quoted above, everybody is right.

> What's standard said about this?

Friend functions are inaccessible outside class scope unless declared in
namespace scope.
The body of an inline friend function is not in local scope in namespace
scope.

Chris

Alberto Ganesh Barbati

unread,
Aug 7, 2006, 1:33:31 PM8/7/06
to
Lin Jen-Shin ha scritto:

> class Dummy{
> friend void hi(){ std::cout << "hi" << std::endl; }
> };
>
> "hi" is a namespace level function, not a method of Dummy.

Yes, but unless there's also a definition at namespace level, it won't
be found by normal lookup but only through ADL. However, in this case,
as hi() has no parameters, ADL never kicks in, so it can't be found at
all.

> Consider codes below:
>
> class Dummy{
> friend void hi(){ std::cout << "hi" << std::endl; }
> friend void hello(){ ::hi(); }
> };
>
> I've tried 3 compilers to compile above code, which are
>
> a) g++ 3.4.5
> b) VC++ 7.1
> c) Comeau C/C++ 4.3.3
>
> with all warning on and strict mode in standard.
>
> g++ compiled fine, while the others failed.

Then g++ is wrong, the others right, according to me. hi() can't be
found, as I said before, even if fully qualified.

> If I didn't know things wrong, which VC++ 7.1 said "argument-dependent
> lookup"
> was also called "Koneig Lookup", which I got from
> http://en.wikipedia.org/wiki/Koenig_lookup.
> And it is in standard, right?

Of course it is!

> However, what makes me wonder most is that if I add codes below front
> of friend:
>
> extern void hi();
>
> Then VC++ 7.1 and Comeau C/C++ 4.3.3 compiled fine, linked fine.

Sure, as I said, adding a namespace level declaration makes the
function visible even through normal lookup.

> If I provide another definition of ::hi():
>
> void hi(){}
>
> then all of the compilers complained about "multi-definition" in
> compile time.

Correct, because in this case you have provided two definitions for the
same function,violating ODR.

> Moreover, if I didn't use strict mode in Comeau C/C++ 4.3.3, then it
> compiled
> fine just as g++ 3.4.5 did, no need to provide additional forward
> declaration.

That's why it's called "strict" mode ;-) The rule that makes hi() not
visible through normal lookup was not present in early implementations
of C++ so it seems that Comeau "relaxed" mode is following that early
(no longer conformant) interpretation.

Hope it helps,

Ganesh

SuperKoko

unread,
Aug 10, 2006, 10:49:21 AM8/10/06
to

"Kristof Zelechovski" wrote:
> Uzytkownik "Lin Jen-Shin" <god...@gmail.com> napisal w wiadomosci
> > Moreover, if I didn't use strict mode in Comeau C/C++ 4.3.3, then it
> > compiled
> > fine just as g++ 3.4.5 did, no need to provide additional forward
> > declaration.
> >
>
> Compilers are free to compile ill-formed code. However, such code is
> unnecessarily unportable.
>
But the compiler must diagnose the ill-formed code (displaying a
warning message to the user):

" 1.3 Implementation compliance
[intro.compliance]

5 A conforming implementation may have extensions (including
additional
library functions), provided they do not alter the behavior of
any
well-formed program. Implementations are required to diagnose
pro-
grams that use such extensions that are ill-formed according to
this
Standard. Having done so, however, they can compile and execute
such
programs.
"

> > So, who is right and who is wrong?
>
> By the rule I quoted above, everybody is right.
>

I tested with GCC 4.0.2:
g++ -Wall -Wextra --pedantic-errors -std=c++98 test.cpp

No error or warning message is displayed.
It is a bug that should be reported (Plus, GCC tries to forbid
ill-formed code when --pedantic-errors is passed).

0 new messages