1

I would like to make use of C99 designated array initialisers to help make my code more self-documenting but I'm running into the problem described below.

Suppose I have a enumeration and an array mapping the enumerants to some other useful data structure, for example:

enum { STATE_IDLE = 0, STATE_WORKING, STATE_PANIC };
int32_t const g_stress_levels[3] = {
        [STATE_IDLE] = 10,
        [STATE_WORKING] = 40,
        [STATE_PANIC] = 90
};

The above compiles with no warnings with TDM-GCC-32 gcc 4.8.1 and -std=c99. The snippet below does not and instead raises the error "array index in initialiser exceeds array bounds".

enum { STATE_IDLE = 0, STATE_WORKING, STATE_PANIC, TOTAL_STATES };
int32_t const g_stress_levels[TOTAL_STATES] = {
        [STATE_IDLE] = 10,
        [STATE_WORKING] = 40,
        [STATE_PANIC] = 90
};

The GCC docs state "the index values must be constant expressions, even if the array being initialized is automatic". I've always thought however that enum is a constant expression, so why might this be the case?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
alteous
  • 188
  • 2
  • 6
  • 1
    This code is absolutely valid. [It compiles and runs perfectly using gcc](http://ideone.com/dXnbgH). If your compiler generates an error, it's a bug in your compiler. Voting to close as "cannot reproduce". – Sergey Kalinichenko May 08 '16 at 11:50

2 Answers2

2

The code runs fine, as expected*:

gsamaras@gsamaras-A15:~$ cat px.c
#include <stdint.h>

enum { STATE_IDLE = 0, STATE_WORKING, STATE_PANIC, TOTAL_STATES };
int32_t const g_stress_levels[TOTAL_STATES] = {
        [STATE_IDLE] = 10,
        [STATE_WORKING] = 40,
        [STATE_PANIC] = 90
};

int main(void) {
    return 0;
}
gsamaras@gsamaras-A15:~$ gcc -Wall -std=c99 -o px px.c
gsamaras@gsamaras-A15:~$ 

The problem must lie somewhere else. You also check it live here.

*Can enum member be the size of an array in ANSI-C?

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
1

it's not a bug in GCC, but you initializing out of bound.

OK:

#define profil_a = 0
#define profil_b = 1
foo_ini [ profil_a, profil_b ];

Error:

//#define profil_a = 0
#define profil_b = 1
foo_ini [ profil_b ];

Fix:

//#define profil_a = 0
#define profil_b = 0
foo_ini [ profil_b ];
ShellX3
  • 51
  • 8