In the following program, default constructor of struct A
does not initialize its field v
. Then in a constant expression, std::vector<A>
is emplaced with A()
object:
#include <vector>
struct A {
constexpr A() noexcept {}
int v;
};
constexpr bool f() {
std::vector<A> as;
as.reserve(1);
as.emplace_back();
return true;
}
static_assert( f() );
MSVC compiler complains about the reading of uninitialized variable:
<source>(14): error C2131: expression did not evaluate to a constant
<source>(11): note: failure was caused by a read of an uninitialized symbol
<source>(11): note: see usage of 'A::v'
But both GCC and Clang are fine with the program. Online demo: https://godbolt.org/z/addx11aTT
Which compiler is correct here?
v
is read in this code (as reported by the message) -- just conjecturing here, perhaps it is an interaction with MSVC debug-build code to detect uninitialized access? – Pentylenetetrazolas.emplace_back();
returns an unused reference to the appendedA
object. And that contains an uninitialized value. – Demersstd::vector
that might copy/move the indeterminate value. So no modifications except decreasing capacity, increasing capacity only from empty state, and adding/removing elements at/from the end (if capacity is free). No copying of the vector itself either. – Declaim