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

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

 



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.

> 2) Is it intentional that this practically removes the ability of
> passing this functions to a function pointer, as in this case I do not
> have an actual argument and therefore argument-dependent-name-lookup
> (adnl) does not apply? (In principle, the compiler would be able to know
> from the l-value expression where to find "f".)

Just add a declaration visible at the point of use.  E.g.,

class C;
C& f (C&x);
class C {
public:
  friend C& f (C& x) { return x; }
};
int main () {
  C c;
  f( c );	// okay, found by adnl
  C & (*ptr) (C&) = f; // error
}

Ian

[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