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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





Ian Lance Taylor schrieb:
Daniel Lohmann <daniel.lohmann@xxxxxxxxxxxxxxxxxxxxxxxxxx> 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



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux