Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does member y get set to 0 in the following code?

I can't make out why this happens. I'm using a bunch of really complicated structures, unions, unnamed versions of both, static variables, etc... but I'm sure this should work. After a day of debugging, I've narrowed my problem to what happens in the following code. I'm using -fms-extensions, which doesn't seem to play nicely with this situation:

//main.c
//Why does y get set to 0 in the case of 'Breaks'?
//Compile with gcc -fms-extensions main.c

#include <stdio.h>

struct Base {
    int x;
    int y;
};

struct Extend {
    union {
        int X;
        struct Base;
    };
};

struct AlsoExtend {
    struct Base;
    int z;
};

static struct Extend Works = {
    .x = 5,
    .y = 3,
    //.X = 2
};

static struct Extend Breaks = {
    .x = 5,
    .y = 3,
    .X = 2
};

static struct AlsoExtend AlsoWorks = {
    .x = 5,
    .y = 3,
    .z = 69
};

int main(int argc, char** argv) {

    printf("Works: x:%d y:%d X:%d\n", Works.x, Works.y, Works.X);
    printf("Breaks: x:%d y:%d X:%d\n", Breaks.x, Breaks.y, Breaks.X);
    printf("AlsoWorks: x:%d y:%d z:%d\n", AlsoWorks.x, AlsoWorks.y, AlsoWorks.z);

    return 0;
}
like image 691
James Newman Avatar asked Oct 19 '25 10:10

James Newman


1 Answers

The C99 specification states this:

When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.

Here, you write one value using one object of a union type and after you try to access the other object of this union type. This leads to unpredictable value in your type.

Thus, you can't do something like this. You should only use one object of the union for a same instance of a struct.

like image 59
lbonn Avatar answered Oct 22 '25 00:10

lbonn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!