You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC编译代码修改thread_local std::deque时崩溃原因排查

GCC编译后std::deque的thread_local成员触发段错误,Clang正常的问题分析

问题重现

以下代码在Clang(Homebrew clang 16.0.2)下编译运行正常,但GCC(Homebrew GCC 13.1.0)编译后触发SIGSEGV崩溃:

test.hpp

#pragma once

#include <deque>

struct A {
    static thread_local std::deque<int> g;
};

test.cpp

#include "test.hpp"

thread_local std::deque<int> A::g = std::deque<int>();

main.cpp

#include "test.hpp"

int main() {
    A::g.emplace_back(0);
    return 0;
}

编译命令

  • Clang编译:
clang++ -std=c++20 main.cpp test.cpp -o run
  • GCC编译(两种方式均崩溃):
g++-13 -std=c++20 main.cpp test.cpp -o run

或

g++-13 -std=c++20 -pthread -c test.cpp main.cpp && g++-13 -pthread test.o main.o -o run

崩溃提示:

[1]    95879 segmentation fault  ./run

系统环境:macOS Monterey 12.5.1

结论

这是GCC在macOS平台上的已知bug,你的代码本身完全符合C++标准,没有错误。

原因分析

  1. 代码语法与逻辑合规:类的static thread_local成员声明、定义及初始化均符合C++标准要求。
  2. 问题根源在于GCC对macOS平台下thread_local变量的初始化逻辑缺陷:主线程访问A::g时,GCC未能正确完成std::deque的构造初始化,导致容器内部指针为NULL,调用emplace_back时触发内存访问错误。
  3. 替换为std::vector后正常,是因为vector的内存布局和初始化时机与deque存在差异,避开了GCC的这个bug。

临时解决方案

可以通过延迟初始化的方式绕过该问题,将成员变量改为返回引用的静态函数:

struct A {
    static auto& g() {
        static thread_local std::deque<int> instance;
        return instance;
    }
};

在main中调用:

int main() {
    A::g().emplace_back(0);
    return 0;
}

此外,尝试升级到更新版本的GCC,后续版本大概率修复了该平台的thread_local容器初始化问题。

内容的提问来源于stack exchange,提问作者tigrkoshka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 18:57:34