C Constant structures containing arrays of different lengths on the stack

I'm interested in creating a struct in C that (among other POD types) holds an array and then creates global instances of that on the stack. The length of the array is known at compile time, but will be different for each instance of the structure. The values ​​inside each instance of the structure will not change and therefore must be set to const.

I currently have the following code:

#ifdef __cplusplus
    extern "C" {
#endif

#include "stdio.h"


typedef struct A
{
   int x;
   int y;
   int* z;
} A_t;

const A_t test[2]  = { {1,1, (int[3]){1,1,1}     },
                       {2,2, (int[5]){2,2,2,2,2} }
                     };

int main( void )
{
    printf( "test[0]: %d %d (%d, %d, %d)\n",
        test[0].x,
        test[0].y,
        test[0].z[0],
        test[0].z[1],
        test[0].z[2] );
    printf( "test[1]: %d %d (%d, %d, %d, %d, %d)\n",
        test[1].x,
        test[1].y,
        test[1].z[0],
        test[1].z[1],
        test[1].z[2],
        test[1].z[3],
        test[1].z[4] );
    printf( "\n\n" );


    return;
}

#ifdef __cplusplus
    }
#endif

      

This will work with an embedded system where the heap is extremely limited, so I want to avoid malloc unless I need to. I also want to stick with C89 if possible as VS2008 does not support C99 (I think).

This works fine in GCC (4.8.1 via MinGW), but doesn't compile in Visual Studio 2008. Does anyone have any suggestions as to how I can get it to work on both compilers?

For reference, here is the error message from VS2008:

c: \ temp \ test_variable_length_arrays \ bob.c (15): error C2059: syntax error: '{'

c: \ temp \ test_variable_length_arrays \ bob.c (15): error C2059: syntax error: '}'

c: \ temp \ test_variable_length_arrays \ bob.c (17): error C2059: syntax error: '}

Thanks for all the comments.

+3


source to share


3 answers


You can allocate internal structures globally and then assign to a structure at runtime, for example.

int x[] = {1,1,1};
int y[] = {3,3,3,3,3};

int main()
{
    A_t str = {2, 2, y};
}

      



I believe that some compilers will also allow you to move the definition str

to the global scope to make it completely static.

+6


source


Visual Studio is choking on the following:

const A_t test[2]  = { {1,1, (int[3]){1,1,1}     },
                       {2,2, (int[5]){2,2,2,2,2} }

      



specifically, join literals (int[3]){1,1,1}

and (int[5]){2,2,2,2,2}

; complex literals were introduced since C99 and will not be recognized by a C89 compiler such as Visual Studio.

Does it need to be compiled by Visual Studio? Can you build it with MinGW (GNU GNU compiler) or with gcc under cygwin perhaps? If not, then the sligoning solution is likely to be the path of least resistance.

+2


source


See comments for syntax (int[3]){1,2,3}

. But there is no guarantee that these arrays will persist in memory (they are temporary). You can define them as global variables and set pointers to them:

static int az1[] = {1, 2, 3};
static int az2[] = {1, 2, 3, 4, 5};
const A_t test[2]  = { {1,1, az1 },
                       {2,2, az2 }
                     };

      

-1


source







All Articles