6
votes

Consider the code:

#include <atomic>
#include <iostream>

struct stru {
  int a{};
  int b{};
};

int main() {
  std::atomic<stru> as;
  auto s = as.load();
  std::cout << s.a << ' ' << s.b << std::endl;
}

Note that although stru has default member initializer, it still qualifies as an aggregate type since C++14. std::atomic has a trivial default constructor. According to the standard, should the members of as be initialized to zero? clang 6.0.0 doesn't do this (see here), while gcc 7.2.0 seems so (see here).

2

2 Answers

4
votes

Strictly speaking, I think both compilers are right, in that your program exhibits undefined behavior. To quote n4140 (C++14), [atomics.types.operations.req], emphasis mine:

In the following operation definitions:

  • an A refers to one of the atomic types.

[...]

A::A() noexcept = default;

Effects: leaves the atomic object in an uninitialized state. [ Note: These semantics ensure compatibility with C. — end note ]

as is uninitialized before the load. So the usual spiel about undefined behavior must follow.

0
votes

According to cppreference the std::atomic::atomic() constructor doesn't initialize the obj:

atomic() noexcept = default;

1) The default constructor is trivial: no initialization takes place other than zero initialization of static and thread-local objects. std::atomic_init may be used to complete initialization.