https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79561
Bug ID: 79561 Summary: Missed optimization: useless guards for zero-initialized POD statics at function scope. Product: gcc Version: 7.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: marc.mutz at kdab dot com Target Milestone: --- Example code: ====BEGIN==== #include <atomic> #include <type_traits> template <typename T> class BasicAtomic { public: std::atomic<T> v; BasicAtomic() = default; constexpr BasicAtomic(T t) noexcept : v(t) {} BasicAtomic(const BasicAtomic&) = delete; BasicAtomic &operator=(const BasicAtomic &) = delete; BasicAtomic &operator=(const BasicAtomic &) volatile = delete; }; static_assert(std::is_pod<BasicAtomic<int>>::value, "oops"); static BasicAtomic<int> s_dyn; int f(const char *str) { while (*str++) ++s_dyn.v; return s_dyn.v; } int f_dynamic_init(const char *str) { static BasicAtomic<int> counter; while (*str++) ++counter.v; return counter.v; } int f_static_init(const char *str) { static BasicAtomic<int> counter = {0}; while (*str++) ++counter.v; return counter.v; } ====END==== GCC (all the way up to 7.0.1) adds a guard for f_dynamic_init(const char*)::counter (but not for the other two). Clang 3.9.1 doesn't. See the difference here: https://godbolt.org/g/erFlRq