Search code examples
c++vectorinitializationundefined-behavior

Does having a vector containing structs with uninitialized members lead to undefined behavior


If you have a vector containing structs with uninitialized members, is this undefined behavior. The context for this is a vector which is created but then filled in a parallel context, Thus the default initialization of the vector is wasted.

Example

template< typename T >
struct uninitialized
{
    T t;
    uninitialized(){};
    uninitialized & operator=( T const & inT ){ t = inT             ; return *this; }
    uninitialized & operator=( T      && inT ){ t = std::move( inT ); return *this; }
};

std::vector< uninitialized< int > > example()
{
    auto vector = std::vector< uninitialized< int > >(500);

    // Other code unrelated to vector

    for( auto & element : vector ) element = 0; // For loop as stand in for potentially parallel context
    // "0" is simply used as a stand in to keep the example simple

    // Code which might use vector

    return vector;
}

Worth mentioning, the uninitialized members will never be read before they are eventually initialized.

If it matters for the anwser, the intended use is for simple numerical types such as int or aggragate types consisting of those numeric types.

(Also to avoid unnecessary comments, reserve + push_back is not relevant here as the final order of the vector is important)


Solution

  • There is no undefined-behavior (UB) in the posted code:

    • Creating a vector with 500 elements is OK:

      auto vector = std::vector<uninitialized<int>>(500);
      

      All the elements will be constructed with uninitialized's default constructor. The fact that it does not initialize T t is immeterial here.

    • The loop with assigments is also OK:

      for( auto & element : vector ) element = 0;
      

      All the elements will be assigned via uninitialized::operator=(T const & inT ) and their T t will be set to 0.

    You can only have UB if you attempt to read an initialized value, but you mentioned that you will not do that, so you should be OK.