Compiling the following example with -O2 in Clang 3.9 will return the returned garbage ( 1.9038e+185 ) when called in main :
Code
double reproFunction(const Eigen::Matrix3d& R_in) { const Eigen::Matrix3d R = R_in; Eigen::Matrix3d Q = R.cwiseAbs(); if(R(1,2) < 2) { Eigen::Vector3d n{0, 1, R(1, 2)}; double s2 = R(1,2); s2 /= n.norm(); } return R(1, 2); } int main() { Eigen::Matrix3d R; R = Eigen::Matrix3d::Zero(3,3); // This fails - reproFunction(R) returns 0 R(1, 2) = 0.7; double R12 = reproFunction(R); bool are_they_equal = (R12 == R(1,2)); std::cout << "R12 == R(1,2): " << are_they_equal << std::endl; std::cout << "R12: " << R12 << std::endl; std::cout << "R(1, 2): " << R(1, 2) << std::endl; }
Output
R12 == R(1,2): 0 R12: 1.9036e+185 R(1, 2): 0.7
reproFunction , initializes R (which is const) to the destination of R_in . It returns R(1, 2) . Between assignment and return, reproFunction uses R in several operations, but none of them can change R When deleting any of these operations, the result of reproFunction returns the correct value.
This behavior does not appear in any of the following cases:
- The program is compiled using Clang 3.5, Clang 4.0 or g ++ - 5.4.
- Optimization level
-O1 or lower - Instead of Eigen 3.3.3, Eigen 3.2.10 is used
Now the question is: Is this behavior due to an error that I missed in the above code, an error in Eigen 3.3.3, or an error in Clang 3.9?
An example of self-contained playback can be found at https://github.com/avalenzu/eigen-clang-weirdness .
source share