简体   繁体   中英

“incompatible types when initializing type” after initializing an struct with an union inside

After implementing the data structure suggested in this thread , I decided to fill it with some test values.

The code is

typedef enum {car, gun, bullet} itemtype;

typedef struct bullettype {
    unsigned short velocity;
    unsigned short kinetic_energy;
} Bullet;

typedef struct cartype {
    unsigned short maxspeed;
} Car;

typedef enum {handgun, shotgun, machinegun} weapontype;

typedef struct firearmtype {
    weapontype type;
    char capacity;
} Firearm;

typedef struct gameitem {
    itemtype type;
    char* name;
    unsigned short bulk; 
    unsigned short weight;
    union {
        Car c;
        Bullet b;
        Firearm f;
    };
} Item;

int main() {
    Item *objects = malloc(50 *sizeof(Item));
    objects[0] = (Item) {gun, "a gun", 500, 5000, (Firearm) {handgun, 10}};
    objects[1] = (Item) {car, "a car", 3500, 4000, (Car) {200}};
    objects[2] = (Item) {bullet, "a bullet", 200, 3000, (Bullet) {300, 5000}};
    free(objects);
    return 0;
}

But when I compile it, I get

itemlisttest.c:40:2: error: incompatible types when initializing type ‘short unsigned int’ using type ‘Firearm’
itemlisttest.c:42:3: error: incompatible types when initializing type ‘short unsigned int’ using type ‘Bullet’

Which means the car item is working fine. And it's listed first in the union inside the struct. So I decided to swap Car and Bullet in the union like this

union {
    Bullet b;
    Car c;
    Firearm f;
};

And the compiler error is now

itemlisttest.c:40:2: error: incompatible types when initializing type ‘short unsigned int’ using type ‘Firearm’
itemlisttest.c:41:2: error: incompatible types when initializing type ‘short unsigned int’ using type ‘Car’

Does this have to do with the way I'm initializing the structs? I'm doing it like that because it will be a long list and 1000 object[a].name = "name" lines don't look pretty at all.

With pre-C99 C you could initialize only the first member of the union. However, starting with C99 if you provide a name for the union member, you could use C99 feature of designated initializers:

typedef struct gameitem {
    itemtype type;
    char* name;
    unsigned short bulk;
    unsigned short weight;
    union {
        Car c;
        Bullet b;
        Firearm f;
    }u;
} Item;

objects[0] = (Item) {gun, "a gun", 500, 5000, .u.f=(Firearm) {handgun, 10}};
objects[1] = (Item) {car, "a car", 3500, 4000, .u.c=(Car) {200}};
objects[2] = (Item) {bullet, "a bullet", 200, 3000, .u.b=(Bullet) {300, 5000}};

You didn't provide a name for the union field:

union {
    Bullet b;
    Car c;
    Firearm f;
} field_name_in_gameitem_struct;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM