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