Temporaries May Vanish Before You Expect - Red Hat ENTERPRISE LINUX 3 - USING GCC Using Instructions

Using the gnu compiler collection (gcc)
Hide thumbs Also See for ENTERPRISE LINUX 3 - USING GCC:
Table of Contents

Advertisement

246
void f () {
foo (1);
int i = N;
T t;
t.bar();
foo (t);
}
static const int N;
};
Here, the names
foo
will thus require that they are defined in the context of use in the template, not only before the point of
instantiation, and will here use
the integer value to a
Conversely,
and the call to
bar
the type of
, so they are only looked up at the point of instantiation, and you can provide declara-
T
tions for them after declaring the template, but before instantiating it. In particular, if you instantiate
, the last line will call an overloaded
A::f int
declaration of
struct A
This distinction between lookup of dependent and non-dependent names is called two-stage (or de-
pendent) name lookup. G++ implements some features of it since version 3.4 and is moving towards
full compliance with the standard.
Two-stage name lookup sometimes leads to situations with behavior different from non-template
codes. The most common is probably this:
template
typename T
int i;
};
template
typename T
int get_i() { return i; }
};
In
,
is not used in a dependent context, so the compiler will look for a name declared at the
get_i()
i
enclosing namespace scope (which is the global scope here). It will not look into the base class, since
that is dependent and you may declare specializations of
compiler can't really know what
error message.
In order to make it clear that you want the member of the base class, you need to defer lookup until
instantiation time, at which the base class is known. For this, you need to access
context, by either using
dependent), or using
-declaration.
using
Note that some compilers get this wrong and accept above code without an error. However, this is spu-
rious, since they just don't implement two-stage name lookup correctly. This includes G++ versions
prior to 3.4.

11.9.3. Temporaries May Vanish Before You Expect

It is dangerous to use pointers or references to portions of a temporary object. The compiler may very
well delete the object before you expect it to, leaving a pointer to garbage. The most common place
where this problem crops up is in classes like string classes, especially ones that define a conversion
function to type
char *
// 1
// 2
// 3
// 4
and
appear in a context that does not depend on the type of
N
::foo(double)
when passing it to
double
in the fourth marked line are used in contexts that do depend on
foo
.
struct Base {
struct Derived : public Base T
would refer to. If there is no global variable
i
(remember that
this- i
. Alternatively,
Base T ::i
or
const char *
Chapter 11. Known Causes of Trouble with GCC
and
, respectively. In particular, it will convert
A::N
::foo(double)
if one was provided, even if after the
::foo(int)
even after declaring
Base
is of type
this
Base T ::i
--which is one reason why the standard
. The compiler
T
.
{
Derived
, then you will get an
i
in a dependent
i
, so is obviously
Derived T *
might be brought into scope by a
string
, so the
class

Advertisement

Table of Contents
loading
Need help?

Need help?

Do you have a question about the ENTERPRISE LINUX 3 - USING GCC and is the answer not in the manual?

Questions and answers

This manual is also suitable for:

Enterprise linux 3

Table of Contents