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
相关产品推荐
相关产品推荐

