Today marks the second time running into this gotcha involving Eigen and C++11's auto
. It may even be a bug.
Here's the little example program:
Eigen::MatrixXd X(2,2);
X<<1,2,
3,4;
const auto mid = (X.colwise().maxCoeff()+X.colwise().minCoeff()).eval()*0.5;
cout<<mid<<endl;
X.setZero();
cout<<mid<<endl;
cout<<(X.colwise().maxCoeff()+X.colwise().minCoeff()).eval()*0.5<<endl;
First I initialize a little matrix and then take the average of it's column-wise max and min vectors and store that in mid
. I'm being careful to use .eval()
because this should truly evaluate the expression. Then I print mid
, zap X
to zero, print mid
again and---to double check---print the expression applied to the new all-zero X
:
With clang this produces:
2 3
1 1.5
0 0
With gcc I get:
2 3
-6.44115e-232 1.34339e+154
0 0
So it seems that after X is set to zeros, mid
contains some random bad value.
Changing auto
above to char
and reading the compiler error message I can reveal the true type of the expression
const ScalarMultipleReturnType {aka const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 1, -1> >}
Okay, so definitely not something simple like Eigen::RowVector<...>
which I'd expected. Not sure why this is returning junk when the values of X change. For now, and for this simple example, the easy solution is to explicitly cast to the type I want:
const RowVector2d mid = (X.colwise().maxCoeff()+X.colwise().minCoeff()).eval()*0.5;