Question Details

No question body available.

Tags

c++ std atomic stdatomic

Answers (2)

January 23, 2026 Score: 10 Rep: 1,651 Quality: Medium Completeness: 50%

This depends a bit on which version of c++ you are on (thanks to @previesta for mentioning it) - though the conclusion will be the same regarding std::atomic:

Pre-C++20:
Your code is be UB irregardless of atomic or not, as C++ requires objects to be constructed explicitely (you cannot just pretend any piece of allocted memory is a "Foo" just because it would fit into the size/is zero-initialized).

If malloc needs to be used to acquire the memory, you'd need to placement new (or std::constructat; which is the example used for std::malloc at cppref) into the malloc-ated area afterwards.

If you can live with the UB, and know your compiler/platform works, then you could probably do it. The atomic constructor is hinted at being default/zero initialized in general, at least due to cppref.

Post-C++20:
Apparently now implicit lifetime types avoids the need of explicit construction for certain types (according to Issue 2489, if I found it correctly). It then depends upon whether "std::atomic", and in extension, "Foo" qualifies for this. For implicit lifetime classes, the requirements are:

- is an aggregate whose destructor is not user-provided(since C++11), or
- has at least one trivial eligible constructor and a trivial, non-deleted destructor.

It now depends on whether or not the constructor of std::atomic is trivial. Unfortunately, std::atomic::(constructor) mentions that from C++20 onwards, the constructor is no longer trivial. So this disqualifies it for implicit lifetime, which in turn disqualifies Foo, which in turn makes the code UB still.

January 23, 2026 Score: 3 Rep: 378,837 Quality: Medium Completeness: 80%

@Juliean answered the language-lawyer version of the question, about what the standard says.

Practically, the concerns are alignment, and running the constructor to init a mutex inside the atomic object if it's non-lock-free and the implementation works that way.


On most normal implementations, it's almost certain that alignof(std::atomic) is less than or equal to alignof(maxalignt) (https://en.cppreference.com/w/cpp/types/maxalignt.html), so a malloc large enough to hold it will also be aligned enough for atomic. A possible exception to this would be a 32-bit or narrower system which doesn't have any standard types which get more than 4-byte alignment, but which can do lock-free atomics on aligned 8-byte objects, and that's what std::atomic uses.

static_assert(alignof(Foo)