简体   繁体   中英

g++ segmentation fault when enabling optimization

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).

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 kl is a dangling reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM