g++ segmentation fault when enabling optimization

c++, optimization, segmentation-fault

Solution

This is wrong:

Expression (L const& l, R const& r) :l(l),r(r){}

L const& l;

You are binding `l` by reference. Then in your usage:

Expression<Expression<doublet, plus, doublet>, plus, doublet> 
    k = b + a + c;

`b + a` creates a temporary, but it exists only until end of statement. In next line `k.l` is a dangling reference.

Problem

Why this code generates segmentation fault, when I enable optimization (flag -O2/-03). When add assert before return, then all OK. ``` #include <iostream> #include <typeinfo> #include <vector> #include <assert.h> struct doublet { doublet(double val1 = 0, double val2 = 0) { dob[0] = val1; dob[1] = val2; } template< class Expr > doublet& operator=(Expr const& x){ dob[0] = x[0]; dob[1] = x[1]; return *this; } const double& operator[](unsigned ix) const { /* * BUG HERE */ //assert(ix<2); return dob[ix]; } void print(){ std::cout << (*this)[0] << std::endl; std::cout << (*this)[1] << std::endl; } private: double dob[2]; }; struct plus { static double apply( double a, double b) { return a + b; } }; struct minus { static double apply(double a, double b){ return a - b; } }; template <class L, class OpTag, class R> struct Expression { Expression (L const& l, R const& r) :l(l),r(r){} L const& l; R const& r; typedef const double result_type; result_type operator[](unsigned ix) const { return OpTag::apply(l[ix],r[ix]); } }; template <class L, class R> Expression<L,plus,R> operator+(L const& l, R const& r){ return Expression<L,plus,R>(l,r); } template <class L, class R> Expression<L,minus,R> operator-(L const& l, R const& r){ return Expression<L,minus,R>(l,r); } int main() { doublet a(4.0,1.0), b(5.1,3.3), c(7.4,5.2); Expression<Expression<doublet, plus, doublet>, plus, doublet> k = b + a + c; std::cout << k[0] << " " << k[1] << std::endl; } ``` Assembler instructions to this code. Segmentation fault reached on 20 line (edx=0). UPDATE. I'll figure out what's problem. For stable working need declare k as doublet or add to Expression class operator=. Case with L const& is not right, because it create template objects (Herb Sutter about const reference to rvalue).

Original source