How to prevent GCC from generating guards for static members

gcc flags
gcc optimization flags
gcc linker options
g++
gcc option file
gcc -i option example
gcc command line options
compiler option

Following is an minimal example that sometimes generates guards and sometimes not:

struct A {
    inline A(int v = 0) {} // without 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; // comment this and uncomment above to try as local-static
    };
//}

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

To summarize:

  • without ctor in class A, guards are never generated
  • using anaon-ns prevents guards also
  • making the static member m a static local in foo() still generates guards (with -fno-threadsafe-statics) (comment/uncomment the appropriate lines in example above)

So, how to grevent guards from being generated in the case class A has a ctor and using anon-ns is not possible?


You can declare the constructor of A as constexpr so that X<A>::m is statically initialized.

If the variable need to be dynamically initialized, then a guard has to be used to prevent multiple initialization.

Per Itanium C++ ABI:

If a function-scope static variable or a static data member with vague linkage (i.e., a static data member of a class template) is dynamically initialized, then there is an associated guard variable which is used to guarantee that construction occurs only once.

Initialization of static variables in C, How do you initialize a static member variable in C++? Generating the Guard Word at Runtime; Putting it all Together; Further Reading; About Stack Smashing Protection. Clang, GCC, and related compilers implement stack smashing protection (SSP) using StackGuard. The fundamental assumption behind the approach is that most stack overflows occur by writing past the end of a function’s stack frame.


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.

static member variable when declared private, outside the class only once using the scope resolution operator (::). Another useful symbol class is ‘s’, representing static functions or data. By default, static functions are always included in the output. To omit them, one can give -i ^s (or -i -s 2) command line option.


inline variables are initialized by each translation unit that includes its definition. Without that guard each translation unit would re-initialize the very same variable.

constexpr constructors, obviously, make the initialization static, so that it doesn't need run-time initialization. But objects that do use dynamic initialization require the guard.

Static In C++, static void foo() { mTop.foo(); } inline static T mTop; }; int main() { B<A>::foo(); } Does anybody know how to disable the generation of an 8-Bytes guard variable  Isolation of variables into a module, using the static keyword, is often better to make sure the module creating the variable is entirely responsible of its state. Now if you want to make your program safer and prevent accessibility of some global variables, go take a look into that map file section.


Static Keyword in C++, The "overall options" allow you to stop this process at an intermediate stage. -​fivopts -fkeep-inline-functions -fkeep-static-functions -fkeep-static-consts -​mstack-size -mstack-guard -mhotpatch=halfwords,halfwords Score Options -meb -mel -fdump-ada-spec[-slim] For C and C++ source and include files, generate​  That's odd because all you have to do to create a class member is to add one word to your member declarations: static in C#, Shared in Visual Basic. In fact, you probably have at least some experience in using class members: If you've ever used the Constant or const declaration then you have, effectively, been working with a class member.


GCC still generates guard variables with -fno-threadsafe-statics, Did you know that when you compile your C or C++ programs, GCC will not With GCC, generating debugging information does not alter code generation. the PIE-related flags (for static linking) for PIC builds (for dynamic linking). Your membership unlocks Red Hat products and technical training on  For example, to build a static library from the source files listed in Example 1-2 using GCC on Unix, create a makefile in the directory johnpaul, as shown in Example 1-20. Example 1-20. Makefile for libjohnpaul.a using GCC on Unix


gcc(1) - Linux manual page - Michael Kerrisk, This option is most useful if you are creating a compiler that should be Use --​disable-shared to build only static libraries. If not linked with libvtv, the verifier will call stub functions (in libstdc++ On certain targets this option sets the default stack clash protection guard size as a power of two in bytes. Generate extra code to write profile information suitable for the analysis program prof. You must use this option when compiling the source files you want data about, and you must also use it when linking. -pg Generate extra code to write profile information suitable for the analysis program gprof. You must use this option when compiling the