Search code examples
cgccstructunionsbit-fields

Gcc: Accessing and initializing unions and bitfields within struct


I have a struct that consists of a union, a variable and a bitfield:

typedef struct router_client {
    union {
        QHsm  *client;
        void (*handler)(QSignal sig, QParam par);
    };
    uint8_t level;
    struct {
        uint8_t presence:2;
        uint8_t is_hsm:1;
        uint8_t is_handler:1;
    };
} router_client_t;

What is the proper way to initialize it? I used to

router_client_t = {.client=(QHsm*)&qhsm_foo, level = l, \
.presence = p, .is_hsm = s, .is_handler = a}

But when switching toolchain from Code Red MCU tools to Cross GCC I started getting

unknown field 'client' specified in initializer
unknown field 'presence' specified in initializer
...

The point of the union is that I want to be able to assign values either to client or handler and let them share the same pointer. I tried a few things and I know I can change the struct but I just wanted to know if there is a C99 way of initializing and accessing it.


Solution

  • This can work. I think that the trick is name of structs and union.

    typedef union {
        int  *client;
        void (*handler)(int sig, int par);
    }union_t;
    
    typedef struct {
        uint8_t presence:2;
        uint8_t is_hsm:1;
        uint8_t is_handler:1;
    }struct_t;
    
    typedef struct router_client {
        union_t test;
        uint8_t level;
        struct_t test2
    } router_client_t;
    
    void main()
    {
        int pippo;
        router_client_t pippo2= {.test.client=(int*)&pippo, .level = 10, .test2.presence = 2, .test2.is_hsm = 1, .test2.is_handler = 1};
    }
    

    Or as you wrote:

    #include <stdint.h>
    
    typedef struct router_client {
        union{
            int  *client;
            void (*handler)(int sig, int par);
        }union_t;
        uint8_t level;
        struct {
            uint8_t presence:2;
            uint8_t is_hsm:1;
            uint8_t is_handler:1;
        }struct_t;
    } router_client_t;
    
    void main()
    {
        int pippo;
        router_client_t pippo2= {.union_t.client=(int*)&pippo, .level = 10, .struct_t.presence = 2, .struct_t.is_hsm = 1, .struct_t.is_handler = 1};
    }