使用Clang 3.9时,为什么返回复制的Matrix3d元素导致输出错误?

And*_*ela 5 clang eigen eigen3

使用-O2on Clang 3.9 编译以下示例会导致reproFunction 1.9038e+185在调用时返回garbage()main:

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;
}
Run Code Online (Sandbox Code Playgroud)

产量

R12 == R(1,2): 0
R12: 1.9036e+185
R(1, 2): 0.7
Run Code Online (Sandbox Code Playgroud)

reproFunction,通过赋值来初始化R(这是const)R_in.它回来了R(1, 2).分配和回报之间,reproFunction使用R中的一些操作,但没有人应该能够改变R.删除任何这些操作会导致reproFunction返回正确的值.

在以下任何情况下都不会出现此问题:

  • 该程序使用Clang 3.5,Clang 4.0或g ++ - 5.4编译.
  • 优化级别是-O1或更低
  • 使用Eigen 3.2.10代替Eigen 3.3.3

现在的问题:这种行为是由于我在上面的代码中遗漏的错误,Eigen 3.3.3中的错误,还是Clang 3.9中的错误?

可以在https://github.com/avalenzu/eigen-clang-weirdness找到一个独立的复制示例.

cht*_*htz 4

我可以用 clang 3.9 重现这个,但不能用 clang 3.8 重现。我将 Eigen 方面的问题一分为二,从 2016-05-24 21:54 开始提交

Bug 256:启用未对齐加载/存储的矢量化。这涉及所有架构和所有规模。可以通过定义 EIGEN_UNALIGNED_VECTORIZE=0 来禁用此新行为

该提交支持对未对齐数据进行矢量化操作。

我仍然认为,这是 clang 中的一个错误,但您可以通过编译来解决它

-D EIGEN_UNALIGNED_VECTORIZE=0
Run Code Online (Sandbox Code Playgroud)

此外,如果检测到 clang 3.9 作为编译器,则可以通过自动禁用此功能来“修复”Eigen。