[GiNaC-devel] Re: strange bug

Christian Bauer Christian.Bauer at uni-mainz.de
Wed Aug 11 17:55:05 CEST 2004


Hi!

On Thu, Jul 15, 2004 at 03:18:01PM +0200, Ralf Stephan wrote:
> I cannot rule out a libstdc++ bug in the (newly installed) version 
> of g++ 3.4. Can you test that?

I also only get this error with g++ 3.4.

Anyway, given this code:

  ex e = lst(symbol("x"), symbol("y"));
  e = e[0];

the presumed sequence of events in the second line is:

 1. ex::operator[]() invokes basic::operator[]() which falls back to
    lst::let_op() because the object is non-const.
 2. lst::let_op() returns a reference to the ex which is the first element
    of the list.
 3. ex::operator=() invokes ptr<basic>::operator=():
    3a. other.p->add_reference() adds one reference to the "x"
    3b. p->remove_reference() deletes the last reference to the list
    3c. delete p destroys the list, including its two ex elements and
        (in succession) the "y"; the "x" remains because there is still one
        reference to it, but this doesn't matter: the ex from the list, a
        reference to which was returned by let_op(), is gone. Hence, the
        "other" inside ptr::operator=() is now a dangling reference.
    3d. p = other.p is undefined because the object referenced by "other"
        no longer exists.

So the problem is that operator[] calls let_op(). Had it called op() like
the const operator[] it would have worked (change to "e = const_cast<const
ex &>(e)[0];" to verify that).

Ok, so the real problem is that there is no way of selecting between the two
versions of operator[] based on whether it is used as an rvalue or an
lvalue. The const-ness of the target is not a strong enough prerequisite.

The same problem exists with matrix::operator() (this also crashes with
gcc 3.3):

  ex e = unit_matrix(2);
  e = ex_to<matrix>(e)(0, 0);

Here, even the const operator() returns a reference (this should be changed!),
so the const-ness of the ex_to<T> result doesn't save you. You have to wrap
the result in a new ex to make it work:

  e = ex(ex_to<matrix>(e)(0, 0));

Suggestions for a solution? Remove the non-const operator[] and require the
explicit use of let_op() to modify lists?

Bye,
Christian

-- 
  / Physics is an algorithm
\/ http://www.uni-mainz.de/~bauec002/



More information about the GiNaC-devel mailing list