From: jamshid@ut-emx.uucp (Jamshid Afshar)
Newsgroups: comp.lang.c++,comp.std.c++
Subject: Re: inlining friend functions
Summary: 'inline friend' legal (and required), BC++ bug
Date: 21 Dec 92 07:35:58 GMT
Reply-To: jamshid@emx.utexas.edu
Followup-To: comp.lang.c++
Organization: The University of Texas at Austin; Austin, Texas

I'm crossposting to comp.std.c++ since I asked this a few months ago but
it was never publicly answered there.

In article <1992Dec16.130156.1@vax1.bham.ac.uk> mccauleyba@vax1.bham.ac.uk (Brian McCauley) writes:
>In article <1992Dec15.182858.22555@aruba.uucp>, sandys@aruba.UUCP (Sandy Schindler) writes:
>>   Error inl.hh, line xx: Storage class 'inline' is not allowed here 
>> Borland will not allow the inline keyword to used on a friend function 
>> inside a class declaration, no matter where the definition happens.
>
>I never put inline in the class definition when declaring friends. Simply
>putting inline in the function definition is sufficient.

Actually, I think 'inline' is *required* in the class declaration if
the function will later be defined inline (and you haven't previously
declared it inline).

	class X {
	   friend void f();// no 'inline', considered 'extern' (11.4)
	};
	inline void f() {} // error: defining 'extern' func inline (7.1.1)

r11.4 says "A function first declared in a friend declaration is
equivalent to an extern declaration".  r7.1.1 says "For a nonmember
function an inline specifier is equivalent to a static specifier for
linkage purposes.  All linkage specifications for a name must agree.
For example,
	[...]
	char* g();	// g() has external linkage
	static char* g() {/*...*/}	// error: inconsistent linkage
".

>As far as I know
>Borland is right and the inline storage class should only appear in a
>function definition and not in a friend declaration that is not also acting
>as the definition.

The grammar allows it:
	member-list: member-declaration ...
	member-declaration: decl-specifiers...
	decl-specifiers: decl-specifiers(opt) decl-specifier
	decl-specifier: friend | fct-specifier
	fct-specifier: inline | virtual

And as I showed above, the language seems to require it.  I'm not sure
if any compiler would actually give an error if you declare a friend
without 'inline' and later define the function inline.  I imagine most
are lax and treat friend functions like member functions: you can
define it inline, even if it was not declared 'inline', at any point
before it's first called.

>> Is this a mere compiler bug on Borland's part, or is this the first 
>> appearance of a standard restriction?

It's a Borland bug that I reported a few months ago when I was porting
the GE COOL library to BC++ 3.1 using real templates.  I littered the
code with '##'-marked comments like:
	/*inline##*/ friend ostream& operator<<(ostream&,const X<T>&);
to indicate a BC++ bug work-around.  The library is available at
cs.utexas.edu in pub/COOL/JCOOL.ZIP; see JCOOL.TXT for more
information.  I highly recommend trying to compile JCOOL if you
use or are beta-testing a compiler supporting templates -- it will
probably find lots of bugs that you can report.

Jamshid Afshar
jamshid@emx.utexas.edu
Newsgroups: comp.lang.c++