Note that there are some explanatory texts on larger screens.

plurals
  1. PODynamic array and prebuilt data
    text
    copied!<p>In C, I am trying to do the following:</p> <pre><code>typedef struct { int length; int items[]; /* 1 */ } wchararray_t; typedef struct { long hash; wchararray_t chars; /* 2 */ } string_t; static string_t s1 = { 617862378, { 5, { 'H', 'e', 'l', 'l', 'o' } } /* 3 */ }; </code></pre> <p>In full words, I would like a type <code>string_t</code> that ends in another type <code>wchararray_t</code> that is itself dynamically sized -- its size being stored in <code>length</code>. Moreover, I would also like to write a prebuilt particular string, as static data, here <code>s1</code> of length 5.</p> <p>The code above assumes C99 support for <code>/* 1 */</code>. The inclusion of the substructure into the bigger structure at <code>/* 2 */</code> is, as far as I understand, not supported even by the C99 standard -- but GCC accepts it. However, at <code>/* 3 */</code> GCC gives up:</p> <pre><code>error: initialization of flexible array member in a nested context </code></pre> <p>As a workaround, the ideal code above is so far written as the following hack, which "kind of works":</p> <pre><code>typedef struct { int length; int items[1]; } wchararray_t; typedef struct { long hash; wchararray_t chars; } string_t; typedef struct { int length; int items[5]; } wchararray_len5_t; typedef struct { long hash; wchararray_len5_t chars; } string_len5_t; static union { string_len5_t a; string_t b; } s1 = { 617862378, { 5, { 'H', 'e', 'l', 'l', 'o' } } }; </code></pre> <p>...and we'd use "s1.b" as the prebuilt string_t (and never refer to "s1.a", which is here only for the static declaration of s1). However, it breaks in the newest GCC 4.8, which optimizes away parts of our code because -- obviously -- any loop over the <code>items</code> of a <code>wchararray_t</code> can iterate only once, given that it is an array of length 1.</p> <p>This particular issue is fixed by giving gcc the option <code>-fno-aggressive-loop-optimizations</code>. It can probably also be fixed by not declaring the length in <code>wchararray_t</code>'s <code>items[]</code> array, making it a dynamic array "just because". However, this way to write code is such a hack that I'd prefer a fully different way to approach the problem...</p> <p>(Note that it is all generated C code produced by PyPy, as opposed to hand-written code; any change is fine, including if it requires changing the way we access the data everywhere, as long as the "valid" C optimizations are not prevented.)</p> <p><strong>EDIT:</strong> replaced "char[]" with "int[]", which doesn't accept the double-quote syntax <code>"hello"</code>. This is because I'm looking for a solution for any array type.</p> <p><strong>NOT RESOLVED:</strong> thanks everybody for your suggestions. It seems there is no clean way, so I have implemented the hackish solution: declaring the types k+1 times, once with a flexible array "int items[];" and the k other times with "int items[N];" for the various values of N that are needed. This requires some additional hacks: e.g. not using flexible arrays for MSVC (they work differently there; I didn't investigate to know if exactly the same syntax would work); and GCC follows what C99 says and is not happy with structs that would contain <code>int items[];</code> as only field. It is however happy if we add a dummy field <code>char _dummy[0];</code>... which is not strictly C99 as far as I know...</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload