2

I want to use code similar to the following (but a lot more complex - this is a simplified example) to initialize an array of structures, but during compilation I get the error "expression must have a constant value".

typedef struct
{
    int x;
    int y;
} windowStruct_t;

static const windowStruct_t windowStructInit =
{
    .x = 3,
    .y = 5,
};

// These get defined differently at times.  This is simplified for the example.
#define NUM_ARRAY_ELEMENTS (2)
#define REPEAT_NUM_ARRAY_ELEMENTS_TIMES(x) (x),(x)

// The following line causes the error "expression must have a constant value" twice.
windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] = 
    { REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };

void someFunction( void )
{
    volatile int x = windowStruct[0].x;
}

void anotherFunction( void )
{
    volatile int y = windowStruct[1].y;
}

Manually expanding the macro and replacing the line that causes the error with the following gives the same result:

windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] = 
    { windowStructInit, windowStructInit };

But this compiles without error:

windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
    { { .x = 3, .y = 5 }, { .x = 3, .y = 5 } };

If I move the array declaration inside of function scope, it compiles without errors (I am ignoring the fact that someFunction() and anotherFunction() now access different arrays and that their lifetimes are different):

void someFunction( void )
{
    windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] = 
        { REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };

    volatile int x = windowStruct[0].x;
}

void anotherFunction( void )
{
    windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] = 
        { REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };

    volatile int y = windowStruct[1].y;
}

Leaving the array declarations inside of function scope, if they are declared to be "static", the error message comes back:

void someFunction( void )
{
    static windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] = 
        { REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };

    volatile int x = windowStruct[0].x;
}

So it seems that when the arrays are declared as automatic variables (on the stack) that they can be initialized in a way that isn't allowed when the memory allocation is static (whether inside function scope or in global scope where the allocation is static even without the "static" keyword). Is there a way to initialize the array in global scope using a const struct as in the original example?

I am using C, not C++. I don't want to use dynamic memory allocation. The compiler is TI's ARM compiler V16.6.0.STS as included in their Code Composer Studio environment.

1 Answers1

3

A const object is not a C constant. Instead use constants which is required for non-automatic storage objects.

Define an initializer { .x = 3, .y = 5 }

typedef struct windowStruct_s {
  int x;
  int y;
} windowStruct_t;

#define windowStruct_t_default_initializer { .x = 3, .y = 5 }
#define NUM_ARRAY_ELEMENTS (2)
#define REPEAT_NUM_ARRAY_ELEMENTS_TIMES(x) x, x /* no () */

windowStruct_t windowStruct[NUM_ARRAY_ELEMENTS] = {
    REPEAT_NUM_ARRAY_ELEMENTS_TIMES(windowStruct_t_default_initializer) };

int someFunction(void) {
  volatile int x = windowStruct[0].x;
  return x;
}

int anotherFunction(void) {
  volatile int y = windowStruct[1].y;
  return y;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256