title: Static structure initialization with a pointer to array of pointers member
body: <p>I'm trying to initialize a structure member that needs to point to an array of pointers. The idea is to declare the array of structures statically to avoid initialization overhead since all the data is fixed and known at compile time.</p>
  
  <p>Unfortunately, I cannot get the code to compile under <code>Visual Studio 2015</code>. The  code listed below produces the following error: <code>C2099: initializer is not a constant</code>. Which seems odd because <code>list</code> is only initialized with a fixed sized list of string literals. </p>
  
  <pre><code>#define DATA_LIST { \
      L"some",        \
      L"example",     \
      L"data",        \
      L"in a list",   \
      NULL            \
  }
  
  #define INFO_LIST { \
      L"another",     \
      L"list",        \
      L"with",        \
      L"some",        \
      L"info",        \
      NULL            \
  }
  
  typedef struct data {
      unsigned int flag;
      const wchar_t **list;
  } dataset, *pdataset;
  
  static dataset somedata[] = {
      {   .flag = 2,
          .list = (const wchar_t *[])DATA_LIST // C2099
      },
      {   .flag = 4,
          .list = (const wchar_t *[])INFO_LIST // C2099
      }
  };
  </code></pre>
  
  <p>I've also tried to use a pointer to a flexible array (<code>const wchar_t *list[];</code>). Not the ideal solution because <code>somedata</code> will no longer be able to be declared as an array of structures. Next to that, it will also produce a warning <code>(C4200: nonstandard extension used: zero-sized array in struct/union)</code>.</p>
  
  <pre><code>typedef struct data {
      unsigned int flag;
      const wchar_t *list[]; // C4200 (somedata can no longer be an array of structures)
  } dataset, *pdataset;
  
  static dataset somedata = {
      .flag = 2,
      .list = DATA_LIST
  };
  </code></pre>
  
  <p>Another idea was to define <code>list</code> as a pointer to a fixed size array of pointers. But this requires the <code>dataset</code> structure to be defined with a <code>list</code> member that is large enough to hold the largest list. Also not ideal when there are lots of small lists and one single large list.</p>
  
  <pre><code>typedef struct data {
      unsigned int flag;
      const wchar_t *list[sizeof (wchar_t *[])INFO_LIST / sizeof *(wchar_t *[])INFO_LIST];
  } dataset, *pdataset;
  
  static dataset somedata[] = {
      {   .flag = 2,
          .list = DATA_LIST
      },
      {   .flag = 4,
          .list = INFO_LIST
      }
  };
  </code></pre>
  
  <p>Maybe I'm overseeing something or is there some language extension feature available that can provide an elegant solution? Any suggestions are welcome.</p>
  
  <p>Note: even though the <code>visual-c++</code> tag is added, the code is compiled as C code.</p>
  
  <hr>
  
  <p>Another interesting thing to add which might be related, is that when <code>somedata</code> is declared as non-static (thus without the <code>static</code> keyword), the compiler will produce some warnings but is able to compile the code. By declaring <code>somedata</code> as non-static, the constraint is removed that forces the data used for initializing <code>somedata</code> to be known at compile time.</p>
  
  <p>As indicated by the compilation warnings, it seems that the compiler temporarily stores the address of the list of string literals in an automatic variable before initializing the <code>list</code> member with it. This remains speculation, though. Maybe someone experienced can shed some light on what is actually happening here.</p>
  
  <pre><code>typedef struct data {
      unsigned int flag;
      const wchar_t **list;
  } dataset, *pdataset;
  
  // C4221: nonstandard extension used: 'list': cannot be initialized using
  //        address of automatic variable '$S1'
  // C4204: nonstandard extension used: non-constant aggregate initializer
  dataset somedata = {
      .flag = 2,
      .list = (const wchar_t *[])DATA_LIST // note: see declaration of '$S1'
  };
  </code></pre>
  
  <p>Last but not least, when using a temporary variable initialized with the address of the list of string literals to initialize the <code>list</code> member, the code finally compiles fine without any warnings or errors.</p>
  
  <pre><code>static const wchar_t *temp[] = DATA_LIST;
  
  static dataset somedata = {
      .flag = 2,
      .list = temp
  };
  </code></pre>
  
  <p>But when declaring <code>temp</code> as a pointer to a pointer and typecasting the list of string literals, the code can no longer be compiled as the expression that initializes <code>list</code> becomes marked as an active error: <code>expression must have a constant value</code></p>
  
  <pre><code>static const wchar_t **temp = (const wchar_t *[])DATA_LIST;
  
  static dataset somedata = {
      .flag = 2,
      .list = temp // marked as active error
  };
  </code></pre>
  
  <p>If I then decide to make <code>somedata</code> non-static again, the expression is no longer marked as an active error. But when trying to compile the code, the following error comes back up again: <code>C2099: initializer is not a constant</code></p>
  
  <p>I'm wondering if <code>Visual Studio 2017</code> behaves the same way and if there is an alternative method available to organize and process the data by similar means.</p>