Search code examples
cstructcompound-literalsc23

How to set a pointer to an integer in a compound literal that is initialized in a function?


I tried to initialise a structure via a compound literal in a function. After solving a part of my problem (see Use of compound literal inside a function to init a variable in C), I have a new problem with one member (ptr_mb) that must be a pointer to a variable.

This is the code:

typedef struct {
  int i_mb;
  int * ptr_mb;
} my_struct_t;

void init_struct(my_struct_t **my_struct, int * const ptr) {
  *my_struct=&(static my_struct_t) {.i_mb=3, .ptr_mb= ptr};
}

int main() {
  int a;
  my_struct_t *my_struct;
  
  // my_struct = &(my_struct_t) {.i_mb=3, .ptr_mb=&a}; It is OK

  // Try to initialize it in a function
  init_struct(&my_struct, &a);
  
}

In main(), it works (cf commented line in the program)

A compilation error was emitted. In the function init_struct, ptr is not a constant (line : *my_struct=&(static my_struct_t) {.i_mb=3, .ptr_mb= ptr};).

a is a variable declared in main(). Thus, its address is constant. I tried to cast the affectation with (int const *), (int * const), (int const * const), .... Sometimes it was nonsense, but just to try and nothing worked.

Is it possible to do such initialisation in a function, the way it works in main()?

(Rq. static is used. I know it is a C23 standard and that standard is not yet published; for detail, see this answer: Use of compound literal inside a function to init a variable in C.)


Solution

  • Simply do not do it during the initialisation. Add one assignment.

    typedef struct {
      int i_mb;
      int * ptr_mb;
    } my_struct_t;
    
    void init_struct(my_struct_t **my_struct, int * const ptr) {
      *my_struct = &(static my_struct_t){.i_mb=3};
      (*my_struct) -> ptr_mb = ptr;
    }
    
    int a = 10;
    int main() {
    
      my_struct_t *my_struct;
      
      // Try to initialize it in a function
      init_struct(&my_struct, &a);  
    
      /* ... */ 
    }