Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Designated Initializer for array of arrays

Tags:

c

c99

We probably know designated initializers in c99 and the way they can be used to initialize large const arrays:

const int vals[] = {
    [0] = 10,
    [10] = 12
}

Which initalizes index 0 of vals to 10 and index 10 of vals to 12.

My question is how to use this style of designated initializers for arrays of arrays. Here is my sample code:

typedef enum {
    COMMON = 0,
    STRINGS,
    KEY,
    PRECUSSIVE,
    GUITAR,
    KEYBOARD,
    BASS,
    PIANO,
    DRUMS,
    _INST_MAX
} instrument_classification_t;
static const int * const instrument_class_hierarchy[] = {
    [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
    [STRINGS] = {GUITAR, BASS, _INST_MAX},
    [KEY] = {PIANO, KEYBOARD, _INST_MAX},
    [PRECUSSIVE] = {DRUMS, _INST_MAX},
    [GUITAR] = NULL,
    [KEYBOARD] = NULL,
    [BASS] = NULL,
    [PIANO] = NULL,
    [DRUMS] = NULL
};

But I get these warnings which imply that initialization is only using the first element.

main.c:166:3: warning: braces around scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
   ^
main.c:166:3: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:15: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
           ^
main.c:166:15: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:24: warning: excess elements in scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
                    ^
main.c:166:24: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:29: warning: excess elements in scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
                         ^
main.c:166:29: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:41: warning: excess elements in scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
                                     ^
main.c:166:41: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:167:3: warning: braces around scalar initializer
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
   ^
main.c:167:3: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:167:16: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
            ^
main.c:167:16: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:167:24: warning: excess elements in scalar initializer
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
                    ^
main.c:167:24: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:167:30: warning: excess elements in scalar initializer
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
                          ^
main.c:167:30: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:168:3: warning: braces around scalar initializer
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
   ^
main.c:168:3: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:168:12: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
        ^
main.c:168:12: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:168:19: warning: excess elements in scalar initializer
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
               ^
main.c:168:19: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:168:29: warning: excess elements in scalar initializer
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
                         ^
main.c:168:29: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:169:3: warning: braces around scalar initializer
   [PRECUSSIVE] = {DRUMS, _INST_MAX},
   ^
main.c:169:3: note: (near initialization for 'instrument_class_hierarchy[3]')
main.c:169:19: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [PRECUSSIVE] = {DRUMS, _INST_MAX},
               ^
main.c:169:19: note: (near initialization for 'instrument_class_hierarchy[3]')
main.c:169:26: warning: excess elements in scalar initializer
   [PRECUSSIVE] = {DRUMS, _INST_MAX},
like image 765
milaniez Avatar asked Feb 05 '23 02:02

milaniez


1 Answers

A braced list of values cannot initialize a pointer. Your error is the same as in:

int *p = { 1, 2, 3 };

You could use a compound literal instead:

// ...
[COMMON] = (const int[]){STRINGS, KEY, PRECUSSIVE, _INST_MAX},

This assumes that the code is at file scope (i.e. outside of any function), which means the compound literals have static storage duration so it is safe to point to them. If your code is actually inside a function, you will need to declare separate static arrays or make some other modification.

like image 63
M.M Avatar answered Mar 02 '23 18:03

M.M