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?

Baruch
  • 19,146
  • 23
  • 122
  • 193
  • @SamerTufail: memset is runtime, OP searches for compile time I be leave! – Klaus May 30 '19 at 09:50
  • Is `#define V 42` `#define INIT4 V, V, V, V` `#define INIT6 INIT4 , V, V` and then placing `#define INIT ` in those `#ifelses` too dumb? With `static int myArr[] = { INIT};` It's not so pretty, but it get's the job done. – Quimby May 30 '19 at 10:02
  • 6
    Is switching to a `std::array` an option? – StoryTeller - Unslander Monica May 30 '19 at 10:08
  • And how about using a library like [Boost.PP](https://www.boost.org/doc/libs/1_70_0/libs/preprocessor/doc/index.html)? – StoryTeller - Unslander Monica May 30 '19 at 10:11
  • 1
    I thought I had a sense of deja vu https://stackoverflow.com/questions/54286610/initialize-an-array-of-compile-time-constant-size-with-incrementing-numbers – StoryTeller - Unslander Monica May 30 '19 at 10:22
  • @StoryTeller I had completely forgotten that I had asked this already! . Although they are not completely the same question (there I needed consecutive numbers, here I need the same number), the answer from there can probably be adapted – Baruch May 30 '19 at 13:36

2 Answers2

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

JVApen
  • 10,617
  • 5
  • 30
  • 64
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

JVApen
  • 10,617
  • 5
  • 30
  • 64
L. F.
  • 18,013
  • 7
  • 41
  • 74