Search code examples
cesp8266esp-idf

Can I use this pointer to struct initialization?


Can I use this type of initialization for a pointer?

/* Globally scoped variables definitions -------------------------------------*/
some_struct_t* PLAYLISTS = &(some_struct_t){0};
some_struct_t* DEVICES = &(some_struct_t){0};

At the moment I'm using this function:

void init_fun()
{
    ...    
    PLAYLISTS = calloc(1, sizeof(*PLAYLISTS));
    assert(PLAYLISTS && "Error allocating memory");

    DEVICES = calloc(1, sizeof(*DEVICES));
    assert(DEVICES && "Error allocating memory");

    ...
}

Context: I am creating a program targeting ESP8266/ESP32 SOC devices that interacts with the Spotify API.


Solution

  • Can I use this type of initialization for a pointer?

    Sure, it is well-defined. The pointers are set to point at compound literals, and since it is done at file scope, those will exist throughout the execution of the program. This is guaranteed by C17 6.5.2.5/5:

    If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

    Although the memory location of those compound literals wouldn't be possible to reuse once you assign the pointers to point somewhere else. It would have been much more sensible to point at a zeroed out struct in flash, since flash is less valuable than RAM.

    However, since this is an embedded system (Why should I not use dynamic memory allocation in embedded systems?) and since it isn't a brilliant idea to make code extra slow just for the heck of it: it would make far more sense to ditch pointers, the compound literals and the malloc calls and instead just memcpy a new value into PLAYLISTS or DEVICES. That way you don't even need them to be pointers.

    Applying the KISS principle, we instead end up with:

    /* Globally scoped variables definitions -------------------------------------*/
    static some_struct_t PLAYLISTS = {0};
    static some_struct_t DEVICES   = {0};
    

    Faster, safer, less memory consuming, more readable.