0

I'm wondering how to intialize a N element std::array of a struct.

Example:

struct SomeStruct {
  uint32_t * const entry1;
  uint16_t * const entry2;
  uint16_t * const entry3;
};

Initialization is possible by:

static const std::array<SomeStruct , 2> arr
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
// nullptr just for example, would be addresses of real variables in the project

But this is not exactly what I need because the following statement works as well without any warning or something else, and therefore leaves elements default initilized.

static const std::array<SomeStruct , 2> arr
{nullptr, nullptr, nullptr, nullptr};

What I need is a strong check of the compiler whether all elements are initialized, in a syntax something like that:

static const std::array<SomeStruct , 2> arr
{{nullptr, nullptr, nullptr}, {nullptr, nullptr, nullptr}};

Is it possible to force C++ to check that all elements of the aggragte type to be initialized?

Tank you!

3
  • If you do aggregate initialization you can actually have the list be empty and all elements will be default initialized. Commented Feb 1, 2017 at 9:06
  • To clarify my previous comment, the compiler is following the C++ specification when it allows you to use fewer members or elements in your initialization, and there's no requirement to warn about it. If you want to force explicit initialization of all elements and all members then you should probably use a static analyzer which can detect this and give warnings about it. Commented Feb 1, 2017 at 9:13
  • What compiler are you using? Are you sure there isn't a optional warning for it? Commented Feb 1, 2017 at 9:17

2 Answers 2

3

But this is not exactly what I need because the following statement works as well without any warning or something else, and therefore leaves elements default initilized.

It does not leave elements default initialized. cppreference on aggregate initialization, emphasis mine:

If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized. If a member of a reference type is one of these remaining members, the program is ill-formed.

The exact wording changed in C++11, but not in a way that affects your case.

So, if you want to initialize all to nullptr, simply use

static const std::array<SomeStruct , 2> arr{};

If you wish for a warning when any element is not explicitly initialized, then you have no portable solution. There is no way for the compiler to know whether the value-initialization of the rest of the array was intentional or not.

A non-portable solution: GCC has a warning flag -Wmissing-field-initializers.

warning: missing initializer for member 'SomeStruct::entry2' [-Wmissing-field-initializers]

{nullptr, nullptr, nullptr, nullptr};
                                   ^
Sign up to request clarification or add additional context in comments.

Comments

0

You could use std::make_array and static_assert the resulting type. The std::make_array is however only a proposal but there is a reference implementation here.

namespace details {
  template<class> struct is_ref_wrapper : std::false_type {};
  template<class T> struct is_ref_wrapper<std::reference_wrapper<T>> : std::true_type {};

  template<class T>
  using not_ref_wrapper = std::experimental::negation<is_ref_wrapper<std::decay_t<T>>>;

  template <class D, class...> struct return_type_helper { using type = D; };
  template <class... Types>
  struct return_type_helper<void, Types...> : std::common_type<Types...> {
      static_assert(std::experimental::conjunction_v<not_ref_wrapper<Types>...>,
                    "Types cannot contain reference_wrappers when D is void");
  };

  template <class D, class... Types>
  using return_type = std::array<typename return_type_helper<D, Types...>::type,
                                 sizeof...(Types)>;
}

template < class D = void, class... Types>
constexpr details::return_type<D, Types...> make_array(Types&&... t) {
  return {std::forward<Types>(t)... };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.