Let's consider the following code (Compiler Explorer):
#include <array>#include <cstddef>#include <new>struct Data{ //Data() {} // TODO int value;};auto test(){ alignas(Data) std::array<std::byte, sizeof(Data)> buffer; buffer.fill(std::byte{0xFF}); auto* const p = new(buffer.data()) Data; const auto value = p->value; p->~Data(); return value;}
What I would expect from this code is that:
- A correctly aligned buffer of
sizeof(Data)
bytes is created and filled with0xFF
. Data
is constructed in it without initializing any value.- Hence, it retains the original memory of the buffer itself.
- And so, under typical circumstances
-1
is returned fromtest
.
Judging from the generated assembly on Compiler Explorer all three compilers:
indeed, do so. In the examples I took newest compiler versions and C++17 but if language version matters here, I'm eager to hear.
Now, if we uncomment the empty Data
constructor (Compiler Explorer):
Data() {} // TODO
Nothing changes for
but for GCC we get -Wuninitialized
warning and the generated code returns now 0
(rather than -1
) which looks like the compiler considers this Undefined Behavior and just did whatever.
Is GCC correct in considering this (I presume) Undefined Behavior and issuing -Wuninitialized
? Or is Clang and MSVC correct in considering this OK?