捕获lambdas中对齐变量的分段错误

时间:2017-06-01 23:37:19

标签: c++ c++11 lambda memory-alignment avx

这个小代码片段与g ++ 6.2.0和clang ++ 3.8.1分段错误:

clang++ -std=c++11 -O3 -mavx -pthreadg++ -std=c++11 -O3 -mavx -pthread

#include <thread>
#include <iostream>

class alignas(32) AlignedObject {
public:
  float dummy[8];
};

int main() {
  while (true) {
    std::thread([](){
      AlignedObject x;
      std::cout << &x;
      std::thread([x](){
        std::cout << &x;
      }).join();
    }).join();
  }

  return 0;
}

查看反汇编,两个编译器都插入了失败的vmovaps指令,这表明编译器生成的对象在某处并未正确对齐。如果-mavx被移除,它可以正常工作,因为指令不再被使用。这是编译器错误还是这段代码依赖于未定义的行为?

1 个答案:

答案 0 :(得分:4)

仅对具有自动存储类的变量观察到alignas(n)__attribute__((aligned(n)))等对齐说明符。但是std::function(由lambda使用)允许(有时需要)动态分配函数闭包,在这种情况下,对齐说明符将被忽略,并且只保证最多std::max_align_t的对齐。

总之,除了将自己的自定义分配器传递给基础std::function之外,具有扩展对齐要求的对象无法通过lambdas中的值安全地捕获,并且必须通过引用捕获。 (我想这更像是std::bind的属性,而不是lambdas的特性)。