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/