7

I have a c-style array whose size is defined by a #define and can change based on compiling options, e.g.

#if LINUX # define SIZE 4 #else # define SIZE 5 #endif static int myArr[SIZE] = { /* ??? */ }; 

How can I initialize the whole array to a non-zero value, for example all 42?

6
  • @SamerTufail: memset is runtime, OP searches for compile time I be leave! Commented May 30, 2019 at 9:50
  • Is #define V 42 #define INIT4 V, V, V, V #define INIT6 INIT4 , V, V and then placing #define INIT <XXX> in those #ifelses too dumb? With static int myArr[] = { INIT}; It's not so pretty, but it get's the job done. Commented May 30, 2019 at 10:02
  • 6
    Is switching to a std::array an option? Commented May 30, 2019 at 10:08
  • And how about using a library like Boost.PP? Commented May 30, 2019 at 10:11
  • 1
    I thought I had a sense of deja vu stackoverflow.com/questions/54286610/… Commented May 30, 2019 at 10:22

3 Answers 3

8

I don't know a solution for C-style arrays, though with constexpr and C++17 you could do this with std::array.

constexpr std::array<int, SIZE> createFilledArray (int value){ std::array<int, SIZE> a{0}; for (auto i = 0; i < SIZE; ++i) a[i] = value; return a; } static constexpr auto myArr = createFilledArray(42); 

Code at compiler explorer

The disadvantage of this is that you can't change the array. If you remove the constexpr from the variable, your compiler should be able to optimize this.

From C++20 on, you can force the initialization:

static constinit auto myArr = createFilledArray(42); 

Not sure if the proposal is already merged in: see constinit proposal

Sign up to request clarification or add additional context in comments.

3 Comments

The loop in your createFilledArray() can be replaced with a.fill(value).
std::array::fill is only declared constexpr in C++20
I need C++11 (as noted by the question tags)
3

If you insist on builtin arrays, you can use static variables in functions:

template <std::size_t N, std::size_t... Is> auto arr_helper2(std::index_sequence<Is...>) -> int (&)[N] { static int arr[N] = {((void)Is, 42)...}; return arr; } template <std::size_t N> auto arr_helper() -> int (&)[N] { return arr_helper2<N>(std::make_index_sequence<N>{}); } static int (&arr)[SIZE] = arr_helper<SIZE>(); 

For example:

int main() { for (std::size_t i = 0; i < SIZE; ++i) std::cout << arr[i] << " "; } 

live demo

Comments

0

For the poor souls who are still limited to C++14, here's a C++14 solution that allows you to fill the C array according to a function fill:

#include <iostream> constexpr int SIZE = 5; constexpr int fill(std::size_t index){ return 42; } template <int INDEX = 0, int... Values> struct Helper : Helper<INDEX + 1, Values..., fill(INDEX)> {}; template <int... Values> struct Helper<SIZE, Values...>{ static constexpr int table[SIZE] = { Values... }; }; template <int... Values> constexpr int Helper<SIZE, Values...>::table[SIZE]; int main() { auto constexpr arr = Helper<0>::table; for(int i = 0; i < SIZE; ++i){ std::cout << arr[i] << '\n'; } } 

However, note that this only works for integral types.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.