Search code examples
initializationg++eigen

Eigen::Vector2f not initialized correctly when compiled with -O2


I faced an issue that a Eigen::Vector2f is not correctly initialized if it is initialized in line with other operations and is compiled e.g. with -O2 flag.

main.cpp

#include <Eigen/Core>
#include <iostream>

int main(int argc, char** argv) {
    const auto x = Eigen::Vector2f(1.0, 2.0);
    const auto delta = Eigen::Vector2f(0.1, 0.2);
    const auto add_1 = x + delta;
    const auto add_2 = Eigen::Vector2f(x.x(), x.y()) + delta;

    std::cout << "x: " << x.x() << ", " << x.y() << std::endl;
    std::cout << "delta: " << delta.x() << ", " << delta.y() << std::endl;
    std::cout << "add_1: " << add_1.x() << ", " << add_1.y() << std::endl;
    std::cout << "add_2: " << add_2.x() << ", " << add_2.y() << " <-- " << std::endl;

    return 0;
}

For add_2, Eigen::Vector2f(x.x(), x.y()) is initialized as (1.0, 2.0) when compiled without optimization, but not with -O2 flag.

w/o optimization

> g++ $(pkg-config --cflags eigen3) main.cpp; ./a.out
x: 1, 2
delta: 0.1, 0.2
add_1: 1.1, 2.2
add_2: 1.1, 2.2 <-- 

with O2

g++ $(pkg-config --cflags eigen3) -O2 main.cpp; ./a.out
x: 1, 2
delta: 0.1, 0.2
add_1: 1.1, 2.2
add_2: 9.97967e+33, 0.2 <-- 

Is initialization as Eigen::Vector2f(x.x(), x.y()) + delta not officially supported?

I'm using g++ 9.4.0 on ubuntu 20.04 with Eigen 3.3.

g++ (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
libeigen3-dev/focal,focal,now 3.3.7-2 all [installed,automatic]

Solution

  • Initializing with Eigen::Vector2f(x.x(), x.y()) + delta is no problem, but if you assign this to an auto expression, you have an expression template which depends on a temporary. See the C++11 and the auto keyword section of common Eigen pitfalls.

    To make your code work, write either

    Eigen::Vector2f const add_2 = Eigen::Vector2f(x.x(), x.y()) + delta;
    // or
    auto const add_2 = (Eigen::Vector2f(x.x(), x.y()) + delta).eval();