c++ - 在 lambda 中捕获对齐变量时出现段错误

标签 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 则效果很好,因为该指令不再使用。这是编译器错误还是此代码依赖于未定义的行为?

最佳答案

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

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

关于c++ - 在 lambda 中捕获对齐变量时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44318653/

相关文章:

c++ - 从 Gtkmm::Table 中删除一行

c++ - sys/types.h 和 linux/types.h 的冲突重新声明

c++ - 为什么 unique_ptr 可以与 std 容器一起使用,例如 vectors<>?

c++ - 从 C++11 中的回调函数终止线程

c++ - 将 std::tuple 的类型转换为 std::pair

c++ - 在 C++ 中使用浮点文字初始化整数数组的成员

c++11 - C++11中有没有更好的方法在堆栈上构造类

c# - 对 Func<T> 进行泛型类型约束

node.js - AWS Lambda 随机超时

c# - 如何将此 lambda 表达式转换为异步/等待?