Patroklos A
Patroklos A

Reputation: 63

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.

Upvotes: 3

Views: 1063

Answers (2)

LPs
LPs

Reputation: 16243

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};
}

Upvotes: 3

user3629249
user3629249

Reputation: 16540

I see an unnamed struct and an unnamed union.

It is highly probably that the cross gcc compiler is not handling anonymous structs and unions with what ever the default standard is.

suggest adding an appropriate parameter to the compile, something like

'-std=c11'

Upvotes: 2

Related Questions