Question

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;
}
Was it helpful?

Solution

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.

OTHER TIPS

As @lbonn says, you're abusing C!

-fms-extensions is a GCC specific option which turns on support for non-standard constructs, including otherwise impossible declarations such as those you attempt above.

The simple answer is: "Don't do that!" Seriously. Don't use -fms-extensions, especially not for your own code! Ever!

Writing declarations that conform to Standard C will hopefully make the problem easier to spot.

Read the text quoted in the answer given @lbonn carefully, and note that 0 is as good of an unspecified value as any other would be.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top