这个小代码片段与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;
}
查看反汇编,两个编译器都插入了失败的vmovaps
指令,这表明编译器生成的对象在某处并未正确对齐。如果-mavx
被移除,它可以正常工作,因为指令不再被使用。这是编译器错误还是这段代码依赖于未定义的行为?
答案 0 :(得分:4)
仅对具有自动存储类的变量观察到alignas(n)
或__attribute__((aligned(n)))
等对齐说明符。但是std::function
(由lambda使用)允许(有时需要)动态分配函数闭包,在这种情况下,对齐说明符将被忽略,并且只保证最多std::max_align_t
的对齐。
总之,除了将自己的自定义分配器传递给基础std::function
之外,具有扩展对齐要求的对象无法通过lambdas中的值安全地捕获,并且必须通过引用捕获。 (我想这更像是std::bind
的属性,而不是lambdas的特性)。