Attempting to declare a previously-declared extern "C" function as a friend within a class definition fails with an error that the friend declaration ambiguates the original extern "C" declaration. It appears that the friend declaration is taken as an overload with "C++" linkage, since G++ then complains that the class members are private within the context of the extern "C" function definition.
$ cat friend.cxx extern "C" { int fork (void); }; class frok { int this_errno; friend int fork (void); }; extern "C" int fork (void) { frok grouped; return grouped.this_errno; } $ g++-4 -c friend.cxx -o friend.o friend.cxx:10:24: error: new declaration 'int fork()' friend.cxx:4:7: error: ambiguates old declaration 'int fork()' friend.cxx: In function 'int fork()': friend.cxx:9:7: error: 'int frok::this_errno' is private friend.cxx:17:18: error: within this context $ According to, for example, "C++ in a nutshell" (http://books.google.co.uk/books?id=91JTA9B_m44C&pg=PA170&lpg=PA170&dq=friend+%22storage+class%22&source=bl&ots=HrN4X1Y5wu&sig=N9rnB8r_YnxbH2hiWGqtbAWbWyk&hl=en&ei=oDt_SqmvGJKNjAe9k93wAQ&sa=X&oi=book_result&ct=result&resnum=5#v=onepage&q=friend%20%22storage%20class%22&f=false), a function in a friend declaration should "retain its original linkage" when it has already been declared. That is referring to the case of applying a storage class specifier (static) to the prior declaration that isn't syntactically valid within a friend declaration, but it seems like it should apply here too; the linkage should still be retained, even though I'm not changing the storage-class specifier. There may be some reason why this isn't valid C++, but I think it's probably a weakness in the parsing of friend declarations. $ g++-4 -v Using built-in specs. Target: i686-pc-cygwin Configured with: /gnu/gcc/gcc-patched/configure --prefix=/opt/gcc-tools -v --wit h-gmp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime -libs --enable-static --enable-shared --enable-shared-libgcc --disable-__cxa_ate xit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --disabl e-symvers --disable-libjava --disable-interpreter --program-suffix=-4 --disable- libgomp --enable-libssp --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TARGET=g++-4 --with-ecj-jar=/usr/share/java/ecj.jar LD=/opt/gcc-tools/bin/ld.exe LD_FOR_TARGE T=/opt/gcc-tools/bin/ld.exe AS=/opt/gcc-tools/bin/as.exe AS_FOR_TARGET=/opt/gcc- tools/bin/as.exe --disable-win32-registry --disable-libgcj-debug --enable-langua ges=c,c++,ada Thread model: posix gcc version 4.5.0 20090730 (experimental) (GCC) -- Summary: Can't declare an extern "C" friend. Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: davek at gcc dot gnu dot org GCC build triplet: i686-pc-cygwin GCC host triplet: i686-pc-cygwin GCC target triplet: i686-pc-cygwin http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41020