New -ffriend-injection behavior - is it really intended?

Daniel Lohmann daniel.lohmann@informatik.uni-erlangen.de
Thu May 24 21:09:00 GMT 2007



Ian Lance Taylor schrieb:
> Daniel Lohmann <daniel.lohmann@informatik.uni-erlangen.de> writes:
> 
>> Today I noticed the new -ffriend-injection behavior of g++ 4.1.x, which
>> I do not really understand:
>>
>> Consider the following code and command line session:
>>
>> // File t.cc
>> 1: class C {
>> 2: public:
>> 3:   friend C& f (C& x) { return x; }
>> 4: };
>> 5: int main () {
>> 6:   C c;
>> 7:   f( c );	// okay, found by adnl
>> 8:   C & (*ptr) (C&) = f; // error
>> 9: }
> 
>> The g++ man page states:
>>
>> *>>>>>
>> -ffriend-injection
>> Inject friend functions into the enclosing namespace, so that they are
>> visible outside the scope of the class in which they are declared.
>> Friend functions were documented to work this way in the old Annotated
>> C++ Reference Manual, and versions of G++ before 4.1 always worked that
>> way.  However, in ISO C++ a friend function which is not declared in an
>> enclosing scope can only be found using argument dependent lookup.  This
>> option causes friends to be injected as they were in earlier releases.
>> This option is for compatibility, and may be removed in a future release
>> of G++.
>> *<<<<<
>>
>>
>> 1) Where can I find this in the standard? From how I understand
>> ISO/IEC 14882:2003 (Second Edition), sec 11.4 "Friend", sentence 5 it
>> should exactly work like the "old behavior". Is my 2003 edition of the
>> standard already outdated?
> 
> Do you mean this?
> 
>    "A function can be defined in a friend declaration of a class if
>     and only if the class is a non-local class (9.8), the function
>     name is unqualified, and the function has namespace scope.  Such a
>     function is implicitly inline.  A friend function defined in a
>     class is in the (lexical) scope of the class in which it is
>     defined.  A friend function defined outside the class is not
>     (3.4.1)."
> 
> There is nothing there which makes the friend function visible to any
> other use.  You need an explicit declaration outside of the class to
> permit other classes to see the function.

Yes, this is exaclty the part I mean.
However, I do not understand how to come to your conclusion:

1) I guess the relevant sentence is: "A friend function defined in a class 
is in the (lexical) scope of the class in which *it* is defined." The 
question is what exactly the *it* refers to. To the class or to the 
function? What makes you sure it refers to the function?
(I should mention that I am not a native speaker, so this might be a simple 
language issue.)

2) In my standard, there is also an illustrating example:
[--example]
class C {
   friend void f() {}
};
[--end example]

The point is, that with the g++ 4.1 interpretation of the standard, f() is 
not visible in *any* scope:

lohmann@faui48a [~]>cat t.cc
class C {
   friend void f() {}

   void g() { f(); }
};

int main() {
   f();
  }

lohmann@faui48a [~]>g++ t.cc
t.cc: In member function 'void C::g()':
t.cc:4: error: 'f' was not declared in this scope
t.cc: In function 'int main()':
t.cc:8: error: 'f' was not declared in this scope
lohmann@faui48a [~]>

If g++ 4.1 interprets the standard in the way that f() is in the lexical 
scope spanned by class C it should be found by g(). If (as older versions 
did) the standard is interpreted in the way that f() is the scope in which 
C is defined, it should be found by main(). But neither scope? If this is 
really correct, it looks like a language defect to me.

3) How do you read from the standard that a friend function defined in a 
class *can* be found from the enclosing namespace (only) by argument 
dependent lookup (as stated in the -ffriend-injection documentation)?

4) And finally, do you know the *intention* behind all this? I am trying to 
imagine a good reason for the g++ 4.1 interpretation, but haven't been able 
to find one so far. I mean, it is just not a strong point for some 
interpretation if it obviously does not make sense...


Ian, please excuse me asking so many questions. Maybe I am totally wrong 
with all this, but this is kind of confusing.

Thanks!

Daniel




More information about the Gcc-help mailing list