1

I have a nested C (gcc-11) struct which contains an array of pointers to another struct. I would like to create a static variable of this type and initialise it at the same time. And all these within a header file. The reason is that it represents some default values which belong to that header file. I don't want to call an initialisation function to set it.

the following compiles OK:

typedef struct s1_s {
        int a;
        int b;
} s1_t;

typedef struct s2_s {
        int c;
        s1_t *s1s; // but I need this to be **s1s really!
} s2_t;

s2_t *def = &(s2_t){
        .c = 10,
        .s1s = &(s1_t){  
                .a = 100,
                .b = 200 
        } 
};
int main(void){ return 1; }

But I would like an array of pointers: s1_t **s1s, to be precise. This does not compile:

typedef struct s1_s {
        int a;
        int b;
} s1_t;

typedef struct s2_s {
        int c;
        s1_t **s1s; // "array" of pointers
} s2_t;

s2_t *def = &(s2_t){
        .c = 10,
        // I want an "array" of 1 *(s1_t*) element
        .s1s = &(s1_t *){{  
                .a = 100,
                .b = 200 
        }} 
};
int main(void){ return 1; }

These are the first errors:

warning: braces around scalar initializer
   15 |         .s1s = &(s1_t *){{
error: field name not in record or union initializer
   16 |                 .a = 100,
...
bliako
  • 977
  • 1
  • 5
  • 16
  • 1
    I don't think it's possible. See https://stackoverflow.com/questions/30603685/c99-pointer-to-compound-literal-array-of-pointers – Barmar Sep 10 '21 at 21:55
  • You really don't want to do this in a header file. In the header file, you should declare the variable. Define it in a .c file. Variable definitions do not belong in a header file. – William Pursell Sep 10 '21 at 22:08
  • 1
    Don't use `_t` suffix on your user defined types. Posix reserves those names for itself. – William Pursell Sep 10 '21 at 22:09
  • Barmar, thanks for the warning but it just did (See @tstanisl's answer)! – bliako Sep 10 '21 at 22:19
  • @William Pursell I will accept your comment about Posix reserving ```_t``` suffixes. Though that's what I have been using for types all my C life. – bliako Sep 10 '21 at 22:22
  • @William Pursell I will disagree with your 1st comment whether variable definitions do not belong in a header file. I see this as a constant so to speak. To contain some global default values. Technically the header file it is in is a ```xyz_private.h``` meaning that only the C library includes and reads it. It's there for readability. The public header that goes along with linking to the library contains ```extern s2_t *defaults;``` thanks for the comment. – bliako Sep 10 '21 at 22:30

1 Answers1

1

Just do this:

s2_t *def = &(s2_t){
        .c = 10,
        // I want an "array" of 1 *(s1_t*) element
        .s1s = (s1_t*[]){&(s1_t){  
                .a = 100,
                .b = 200 
        }} 
};
  • (s1_t*[]) indicates that the compound literal is of type "array of pointers to s1_t". The compiler will automatically infer its size
  • each element of array must be a pointer, therefore it is defined as &(s1_t) { ... }
tstanisl
  • 13,520
  • 2
  • 25
  • 40