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:
parent
c745338420
commit
5cf0212f36
@ -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.
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user