From 7cffcaa55eeae1e1002b5ff3bf12536895bd3c30 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Fri, 16 May 2025 22:50:16 +0200 Subject: [PATCH 1/4] [core] make static vars constexpr for thread safety v3 Fixes https://github.com/root-project/root/issues/18751 All credit goes to vepadulano and guitargeek --- core/foundation/src/TClassEdit.cxx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 392dc7092e726..73d458e278a6b 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -1274,15 +1274,13 @@ int TClassEdit::GetSplit(const char *type, vector& output, int &nestedLo string TClassEdit::CleanType(const char *typeDesc, int mode, const char **tail) { - static const char* remove[] = {"class", "const", "volatile", nullptr}; - auto initLengthsVector = []() { - std::vector create_lengths; - for (int k=0; remove[k]; ++k) { - create_lengths.push_back(strlen(remove[k])); - } - return create_lengths; - }; - static std::vector lengths{ initLengthsVector() }; + constexpr static std::array remove{"class", "const", "volatile"}; + constexpr static auto lengths = []() constexpr { + std::array ret{}; + for(std::size_t i = 0; i < remove.size(); i++) + ret[i] = std::char_traits::length(remove[i]); + return ret; + }(); string result; result.reserve(strlen(typeDesc)*2); @@ -1296,11 +1294,11 @@ string TClassEdit::CleanType(const char *typeDesc, int mode, const char **tail) } if (kbl && (mode>=2 || lev==0)) { //remove "const' etc... int done = 0; - int n = (mode) ? 999 : 1; + int n = (mode) ? static_cast(std::size(remove)) : 1; // loop on all the keywords we want to remove - for (int k=0; k(lengths[k]); // Do we have a match if (strncmp(remove[k],c,rlen)) continue; From 847c6e828aa03898f35e4a15783b70d1ae27acc3 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Fri, 16 May 2025 22:52:28 +0200 Subject: [PATCH 2/4] [nfc] clangf --- core/foundation/src/TClassEdit.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 73d458e278a6b..806a0f684858c 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -1277,7 +1277,7 @@ string TClassEdit::CleanType(const char *typeDesc, int mode, const char **tail) constexpr static std::array remove{"class", "const", "volatile"}; constexpr static auto lengths = []() constexpr { std::array ret{}; - for(std::size_t i = 0; i < remove.size(); i++) + for (std::size_t i = 0; i < remove.size(); i++) ret[i] = std::char_traits::length(remove[i]); return ret; }(); From c07eafe07a1c9c0cf005b7b31d0c9dafce0b5fec Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Fri, 16 May 2025 23:05:32 +0200 Subject: [PATCH 3/4] [core] avoid magic number Co-authored-by: Jonas Rembser --- core/foundation/src/TClassEdit.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 806a0f684858c..93d6739b53a1a 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -1276,7 +1276,7 @@ string TClassEdit::CleanType(const char *typeDesc, int mode, const char **tail) { constexpr static std::array remove{"class", "const", "volatile"}; constexpr static auto lengths = []() constexpr { - std::array ret{}; + std::array ret{}; for (std::size_t i = 0; i < remove.size(); i++) ret[i] = std::char_traits::length(remove[i]); return ret; From ed1131e101a279081cbde69acd17045bf7e8c3e0 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Fri, 16 May 2025 23:13:59 +0200 Subject: [PATCH 4/4] [core] cast to int is unnecessary since strncmp last arg is size_t --- core/foundation/src/TClassEdit.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 93d6739b53a1a..e12cd8d40244e 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -1294,11 +1294,11 @@ string TClassEdit::CleanType(const char *typeDesc, int mode, const char **tail) } if (kbl && (mode>=2 || lev==0)) { //remove "const' etc... int done = 0; - int n = (mode) ? static_cast(std::size(remove)) : 1; + size_t n = (mode) ? std::size(remove) : 1; // loop on all the keywords we want to remove - for (int k = 0; k < n; k++) { - auto rlen = static_cast(lengths[k]); + for (size_t k = 0; k < n; k++) { + auto rlen = lengths[k]; // Do we have a match if (strncmp(remove[k],c,rlen)) continue;