捕获 lambda 中对齐的变量时出现分段错误

Tho*_*mas 1 c++ lambda memory-alignment avx c++11

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

clang++ -std=c++11 -O3 -mavx -pthread 或者 g++ -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;
}
Run Code Online (Sandbox Code Playgroud)

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

Tho*_*mas 5

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

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