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