g++ and suppressing threadsafe-statics

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

g++ and suppressing threadsafe-statics

Klaus Doldinger
Hi all,

following is an example regarding the generation of guards for the
static m in template X.

My goal ist to suppress(!) the generation of the guards (for use on
microcontroller).

1) If no user-defined ctors are used, no guards are generated
2) With anon-ns, no guards are generated

But even

3) if I make it a local static instead as a static member and use
-fno-threadsafe-statics, the guards are generated

Option 1) or 2) are not applicable for me, so I went for option 3), but
that did not work either.

Any hints?
 Wilhelm

// Test für guard variable

struct A {
    inline A(int v = 0) {} // without user-defined ctors, guards are omitted
    int m1() const {
        return m;
    }
private:
    int m = 0;
};

//namespace { // without anon-ns guards, are generated
    template<typename T>
    struct X {
        static int foo() {
//            static T m; // even as local-static and
-fno-threadsafe-statics, guards are generated
            return m.m1();
        }
        inline static T m;
    };
//}

int main() {
    return X<A>::foo();
}

Reply | Threaded
Open this post in threaded view
|

Re: g++ and suppressing threadsafe-statics

Jonathan Wakely-4
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.
Reply | Threaded
Open this post in threaded view
|

Re: g++ and suppressing threadsafe-statics

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.
Reply | Threaded
Open this post in threaded view
|

Re: g++ and suppressing threadsafe-statics

Klaus Doldinger


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.