Am 09.10.19 um 18:12 schrieb Klaus Doldinger: > > > Am 09.10.19 um 11:19 schrieb Jonathan Wakely: >> On Wed, 9 Oct 2019 at 04:49, Klaus Doldinger wrote: >>> >>> Hi all, >>> >>> following is an example regarding the generation of guards for the >>> static m in template X. >> >> I didn't check the implementation, but according to the documentation, >> -fno-threadsafe-statics only affects local static, so it's >> unsurprising that it doesn't have any effect on a static member >> variable. >> >> For the local static variable, GCC and Clang still emit the guard >> variable with -fno-threadsafe-statics but they do not emit the code to >> use that variable (there are no calls to __cxa_guard_acquire or >> __cxa_guard_release). I believe the guard variable stills gets be >> emitted for ABI reasons, because another translation unit compiled >> without -fno-threadsafe-statics might be expecting it to exist. >> > > Ok. Looks like constinit (C++20) and a constexpr user-defined ctor could > solve the problem. > Thanks for pointing me into the right direction. > The full example: The key-feature to suppress guards are constinit and constexpr ctors: #include <cstdint> struct A { inline constexpr A(uint8_t v) : m{v} {} // without constexpr it should not compile, but does anymay auto m1() const { return m; } private: uint8_t m{0}; }; template<typename T> struct X { static auto foo() { return m.m1(); } constinit inline static T m{2}; // requires constexpr ctor }; int main() { return X<A>::foo(); } With constinit the initialization must be performed on compile-time, so there is no need to generate guards. This requires a constexpr ctor. In the above example the ctor (at least for gcc) could be declared without constexpr, but this may be a pending bug.