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

Windows下Clang-Tidy检测RapidJSON的thread_local报错解决咨询

解决跨环境下Clang-Tidy对RapidJSON thread_local的报错问题

项目环境

  • 开发C++17项目,Linux环境下使用GCC 9编译
  • Windows 11的Qt Creator 10中,借助clangd/clangTidy 16.0.0进行代码编辑

自定义代码的thread_local问题解决

代码中使用thread_local时,Clang-Tidy会报错提示当前目标不支持线程本地存储。针对自定义函数,我通过宏区分编译器解决了问题:

auto gmtimeTS( const time_t *timeval ) -> struct tm*
{
    #if ( defined(__GNUC__) && !defined(__clang__) )
        thread_local struct tm result;
    #else
        static std::mutex mtx;
        std::unique_lock< std::mutex > lock( mtx );
        static struct tm result;
    #endif

    return gmtime_r( timeval, &result );
}

这样IDE不再报错,Linux下GCC编译也正常。

RapidJSON的thread_local报错问题

但遇到RapidJSON的类似问题无法解决:即使定义了__clang__,RapidJSON仍会使用thread_local,触发如下错误:

rapidjson/document.h:1237:35: error: thread-local storage is not supported for the current target [clang-diagnostic-error]
alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];

查看document.h的相关代码发现,当RAPIDJSON_HAS_CXX11启用时(C++17满足启用条件),会强制使用thread_local:

...
...
#ifndef RAPIDJSON_HAS_CXX11
#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L)
#endif
...
...
#if RAPIDJSON_HAS_CXX11
            // Use thread-local storage to prevent races between threads.
            // Use static buffer and placement-new to prevent destruction, with
            // alignas() to ensure proper alignment.
            alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
            return *new (buffer) GenericValue();
#elif defined(_MSC_VER) && _MSC_VER < 1900
            // There's no way to solve both thread locality and proper alignment
            // simultaneously.
            __declspec(thread) static char buffer[sizeof(GenericValue)];
            return *new (buffer) GenericValue();
#elif defined(__GNUC__) || defined(__clang__)
            // This will generate -Wexit-time-destructors in clang, but that's
            // better than having under-alignment.
            __thread static GenericValue buffer;
            return buffer;
#else
            // Don't know what compiler this is, so don't know how to ensure
            // thread-locality.
            static GenericValue buffer;
            return buffer;
#endif

当前Clang-Tidy调用命令

C:\Qt\Tools\QtCreator\bin\clang\bin\clang-tidy.exe "-config={Checks: '-*,clang-*,concurrency-*,cppcoreguidelines-virtual-class-destructor,misc-misplaced-const,modernize-use-override,-clang-diagnostic-*', CheckOptions: []}" "-export-fixes=C:\Users\XXX\AppData\Local\Temp\QtCreator-RxIOUr\clangtools-RhHPvy\report-test.h-USFhkc" C:\XXX\libs\include\test.h -- -Wno-unknown-pragmas -Wno-unknown-warning-option -Wno-documentation-unknown-command -w -nostdinc -nostdinc++ -g --param "max-vartrack-size=1024000000" -pipe "-fmessage-length=0" "-std=c++17" -fsyntax-only -m64 "--target=x86_64-pc-cygwin" -x c++ "-D_FILE_OFFSET_BITS=64" -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_REENTRANT -IC:A -IC:B ...

需求与最终解决方案

我需要消除Clang-Tidy的报错,同时不影响Linux下GCC的编译。在#include后加//NOLINT无效,尝试通过.clang-tidy文件解决未果,最终通过修改RapidJSON源码实现了需求:

修改后的document.h相关代码:

#if RAPIDJSON_HAS_CXX11 && !defined(RAPIDJSON_NO_THREAD_LOCAL)
            // Use thread-local storage to prevent races between threads.
            // Use static buffer and placement-new to prevent destruction, with
            // alignas() to ensure proper alignment.
            alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
            return *new (buffer) GenericValue();
#elif defined(_MSC_VER) && _MSC_VER < 1900 && !defined(RAPIDJSON_NO_THREAD_LOCAL)
            // There's no way to solve both thread locality and proper alignment
            // simultaneously.
            __declspec(thread) static char buffer[sizeof(GenericValue)];
            return *new (buffer) GenericValue();
#elif (defined(__GNUC__) || defined(__clang__)) && !defined(RAPIDJSON_NO_THREAD_LOCAL)
            // This will generate -Wexit-time-destructors in clang, but that's
            // better than having under-alignment.
            __thread static GenericValue buffer;
            return buffer;
#else
            // Don't know what compiler this is, so don't know how to ensure
            // thread-locality.
            static GenericValue buffer;
            return buffer;
#endif

使用方式:

#if __clang__
    #define RAPIDJSON_NO_THREAD_LOCAL
#endif

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 16:24:53