Home > Back-end >  Error initializing nested struct containing array of struct and function pointer c99 and gnu99
Error initializing nested struct containing array of struct and function pointer c99 and gnu99

Time:01-06

I am getting error during initialization of nested structure containing two members

  • unsigned int
  • typedef void (*vfptr)(void);.

The first structure or parent structure contains simply two variables as shown:

typedef struct Stype1 {
    unsigned int uiVar;
    vfptr  vfptr1;
}Stype1;

The second structure contains above structure as array of struct:

typedef struct Stype2 {
    Stype1  Stype1inst[4];
}Stype2;

Whenever I try to compile using gcc 12.2.1 I get error:

error: expected expression before ‘{’ token
   30 |     Stype2inst.Stype1inst[4] = {{1,(vfptr)Vfun1},

I also tried initializing the structures using designated initializes as mentioned here:

typedef struct Stype2 {
    Stype1  Stype1inst[] = {
        {.uiVar = 1 , .vfptr1 = Vfun1 }
        };
}Stype2;

But I get error:

error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
   24 |     Stype1  Stype1inst[] = {
      |            

Also tried compiling with -std=gnu99 and -std=c99 without any luck.

The entire code is pasted below:


#include <stdio.h>


typedef void (*vfptr)(void);

void Vfun1(){};
void Vfun2(){};
void Vfun3(){};
void Vfun4(){};

typedef struct{
    unsigned int uiVar;
    vfptr  vfptr1;
}Stype1;

typedef struct{
    Stype1  Stype1inst[4];
}Stype2;


Stype2 Stype2inst;

int main()
{
    Stype2inst.Stype1inst[4] = {{1,(vfptr)Vfun1},
                                {2,(vfptr)Vfun2},
                                {3,(vfptr)Vfun3},
                                {4,(vfptr)Vfun4}};
    return 0;
}

CodePudding user response:

Structures and arrays can only be initialised at the point of their declaration. In your case, Stype2inst is declared as a structure, so the declaration-with-initialization will be of the form:

Stype2 Stype2inst = { ... };

Here, the ... will be the initial value(s) of the structure's data. That data is an array (with four elements), so we can now 'expand' the form to the following:

Stype2 Stype2inst = { { e0, e1, e2, e3 } };

Each of the elements (e0 thru e3) will itself be a structure (of type Stype1, and will take the form that you have correctly used: {1,(vfptr)Vfun1} (although the cast here is unnecessary).

Putting all this together and adding line-breaks, spaces and indentation for easy reading, we get the following declaration/initialisation:

Stype2 Stype2inst = {   // Outer braces are for the "Stype2" structure
    {                   // Next are for the enclosed array of "Stype1"
        { 1, Vfun1 },   // Each of these is for one element/structure;
        { 2, Vfun2 },   
        { 3, Vfun3 },   // Note that you don't need the casts to vfptr
        { 4, Vfun4 }
    }
};

Note: Although the much shorter form of initialisation, which you have 'tried' in the comments to the question (and shown below), is valid, it is unclear and potentially ambiguous:

Stype2 Stype2inst = { 1,(vfptr)Vfun1, 2,(vfptr)Vfun2, 3,(vfptr)Vfun3, 4,(vfptr)Vfun4 };

Using this syntax, the clang-cl compiler generates the following diagnostic (four times):

warning : suggest braces around initialization of subobject [-Wmissing-braces]

  • Related