views:

331

answers:

3

Hello,

I've got following code:

File: Foo.h

class Foo {
    friend void Bar();
};

File: Foo.cpp

void Bar() {};

File Test.cpp

#include "Foo.h"

int main(void) {
    Bar();
    return 0;
}

VS2008 compiles this without any error or warning. G++ 4.3.4 reports:

test.cpp: In function ‘int main()’:
test.cpp:8: error: ‘Bar’ was not declared in this scope

Why?

A: 

A friend declaration doesn't count as a prototype. You also need to need a separate prototype:

// File: Foo.h

void Bar();

class Foo {
    friend void Bar();
};
John Kugelman
Could you prove that with a reference to C++ Standard? I couldn't find that.
liori
And what's with `struct X { friend operator<<(std::ostream} };`? It's a pretty common idiom to define a stream operator for class templates within the `friend` declaration and it surely suffices to call the operator.
sbi
sbi, case when a friend function is defined (not only declared) inside class is covered by 11.4.5 ("A function can be defined in a friend declaration of a class if and only if the class is a non-local class, the function name is unqualified, and the function has namespace scope" -- your example fulfils these requirements). I *guess* that standard does allow declaration ("prototype") of a friend function inside class. It is the error g++ is generating which bothers me.
liori
Also 11.4.3: "A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retainsits previous linkage (7.1.1)." I think that seals the deal.
Potatoswatter
A: 

I found this question in the "unanswered" section, but the comments to the previous incorrect answer do constitute a correct answer. Therefore here is a community wiki response with that content.

Summary: GCC appears to be rejecting good code.

case when a friend function is defined (not only declared) inside class is covered by 11.4.5 ("A function can be defined in a friend declaration of a class if and only if the class is a non-local class, the function name is unqualified, and the function has namespace scope" -- your example fulfils these requirements). I guess that standard does allow declaration ("prototype") of a friend function inside class. It is the error g++ is generating which bothers me. – liori Nov 22 at 20:35

Also 11.4.3: "A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retains its previous linkage (7.1.1)." I think that seals the deal. – Potatoswatter 0 secs ago [delete this comment]

Potatoswatter
A: 

You guys rock with knowledge of the standard, that's true. But standard is standard, and implementation of the standard is completely different thing. I guess you guys are using just a single compiler all the time, like MSVC, that seems to follow the standard. While there are tons of other compilers out there.

For me and my humble 5 years experience with C/C++ this is obvious that the Test.cpp does not see the Bar, because it includes just Foo.h that does not have a declaration of Bar.

I gave John Kugelman +1 because his answer resolves the question asked. And it does not spam with knowlendge of standards.

Wizzard
Well, I do use multiple compilers to compile my codebase. And during that I happened to find this exact problem. So this bothers me and I am willing to spend some time asking GCC guys to fix problem, if it is on their side. I just don't feel that good with standards and wanted to ask here first.
liori