trouble.texi: Better document two-stage name lookup.

2003-07-22  Wolfgang Bangerth  <bangerth@dealii.org>
* doc/trouble.texi: Better document two-stage name lookup.

From-SVN: r69675
This commit is contained in:
Wolfgang Bangerth 2003-07-22 11:50:13 -06:00 committed by Wolfgang Bangerth
parent c745338420
commit 5cf0212f36
2 changed files with 48 additions and 8 deletions

View File

@ -1,3 +1,7 @@
2003-07-22 Wolfgang Bangerth <bangerth@dealii.org>
* doc/trouble.texi: Better document two-stage name lookup.
2003-07-22 Eric Christopher <echristo@redhat.com> 2003-07-22 Eric Christopher <echristo@redhat.com>
* config/s390.c (s390_valid_pointer_mode): New. * config/s390.c (s390_valid_pointer_mode): New.

View File

@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
@c 1999, 2000, 2001 Free Software Foundation, Inc. @c 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
@c This is part of the GCC manual. @c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi. @c For copying conditions, see the file gcc.texi.
@ -941,9 +941,8 @@ the last line will call an overloaded @code{::foo(int)} if one was
provided, even if after the declaration of @code{struct A}. provided, even if after the declaration of @code{struct A}.
This distinction between lookup of dependent and non-dependent names is This distinction between lookup of dependent and non-dependent names is
called two-stage (or dependent) name lookup. G++ implements some called two-stage (or dependent) name lookup. G++ implements it
features of it since version 3.4 and is moving towards full compliance since version 3.4.
with the standard.
Two-stage name lookup sometimes leads to situations with behavior Two-stage name lookup sometimes leads to situations with behavior
different from non-template codes. The most common is probably this: different from non-template codes. The most common is probably this:
@ -974,10 +973,47 @@ type @code{Derived<T>*}, so is obviously dependent), or using
@code{Base<T>::i}. Alternatively, @code{Base<T>::i} might be brought @code{Base<T>::i}. Alternatively, @code{Base<T>::i} might be brought
into scope by a @code{using}-declaration. into scope by a @code{using}-declaration.
Note that some compilers get this wrong and accept above code without an Another, similar example involves calling member functions of a base
error. However, this is spurious, since they just don't implement class:
two-stage name lookup correctly. This includes G++ versions prior to
3.4. @example
template <typename T> struct Base @{
int f();
@};
template <typename T> struct Derived : Base<T> @{
int g() @{ return f(); @};
@};
@end example
Again, the call to @code{f()} is not dependent on template arguments
(there are no arguments that depend on the type @code{T}, and it is also
not otherwise specified that the call should be in a dependent context).
Thus a global declaration of such a function must be available, since
the one in the base class is not visible until instantiation time. The
compiler will consequently produce the following error message:
@example
x.cc: In member function `int Derived<T>::g()':
x.cc:6: error: there are no arguments to `f' that depend on a template
parameter, so a declaration of `f' must be available
x.cc:6: error: (if you use `-fpermissive', G++ will accept your code, but
allowing the use of an undeclared name is deprecated)
@end example
To make the code valid either use @code{this->f()}, or
@code{Base<T>::f()}. Using the @code{-fpermissive} flag will also let
the compiler accept the code, by marking all function calls for which no
declaration is visible at the time of definition of the template for
later lookup at instantiation time, as if it were a dependent call.
We do not recommend using @code{-fpermissive} to work around invalid
code, and it will also only catch cases where functions in base classes
are called, not where variables in base classes are used (as in the
example above).
Note that some compilers (including G++ versions prior to 3.4) get these
examples wrong and accept above code without an error. Those compilers
do not implement two-stage name lookup correctly.
@node Temporaries @node Temporaries