Lifetime bug in temporaries
Marc Espie
espie@quatramaran.ens.fr
Tue Mar 24 14:56:00 GMT 1998
// I've got a problem with the lifetime of temporaries. Since the
// corresponding code is short enough, I can post it:
#include <stdlib.h>
#include <iostream>
const size_t SIZE=50;
template<class U>class Expr
{
const U &a;
public:
typedef typename U::value_type value_type;
Expr(const U &x): a(x)
{
cout << "Expr[0] = " << a[0] << endl;
}
value_type operator[](size_t i) const
{
return a[i];
}
};
template<class U, class V>
class SumExpr
{
typedef typename V::value_type value_type;
const U &a;
const V &b;
public:
value_type operator[](size_t i) const
{
return a[i] + b[i];
}
SumExpr(const U &x, const V &y): a(x), b(y)
{
cout << "Sum[0] = " << a[0] << "+" << b[0] << endl;
}
};
template<class T>class Vector
{
typedef T value_type;
value_type value[SIZE];
public:
value_type operator[](size_t i) const
{
return value[i];
}
value_type& operator[](size_t i)
{
return value[i];
}
template<class U>Vector &operator=(const Expr<U>& e)
{
for (size_t i = 0; i < SIZE; i++)
value[i] = e[i];
return *this;
}
};
template<class U>Expr<U> make_expr(const U &v)
{
return Expr<U>(v);
}
template<class U, class V>SumExpr<U, V>make_sum(const U &a, const V &b)
{
return SumExpr<U, V>(a, b);
}
template<class U, class V>inline Expr<SumExpr<Vector<U>, Vector<V> > >
operator+(const Vector<U> &a, const Vector<V> &b)
{
return make_expr(make_sum(a, b));
}
int main()
{
Vector<double> a, b, c;
for (size_t i = 0; i < SIZE; i++)
{
a[i] = 2;
b[i] = 3;
c[i] = i;
}
Vector<double> d;
d = a+b;
for (size_t i = 0; i < SIZE; i++)
cout << d[i] << " ";
cout << endl;
}
/*
for those of you familiar with Blitz++, this should appear
as evident.
However, it crashes (SEGV) with a cvs-current egcs, compiled with
enabled-haifa, on either dec-osf or solaris.
I've investigated it further with gdb-4.16.85.
The crash occurs in SumExpr<..>::operator[]()
It appears that b has been overwritten with a 0.
Setting up a watchpoint, it appears that the overwriting occurs
in
for (size_t i = 0; i < SIZE; i++)
(in Vector::operator=)
Apparently, the compiler uses the same location for my temporary
as per i. Indeed, if I declare i to be static, everything works fine.
My understanding though, is that the SumExpr<..> temporary should
still be alive at this point.
Am I missing something, or is g++ lifetime of temporaries still not in
tune with what it should be ?
*/
More information about the Gcc-bugs
mailing list