3

我无法弄清楚为什么会这样。我正在使用一堆非常复杂的结构、联合、两者的未命名版本、静态变量等......但我确信这应该有效。经过一天的调试,我将问题缩小到以下代码中发生的情况。我正在使用-fms-extensions,它似乎不能很好地适应这种情况:

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

2 回答 2

5

C99 规范说明了这 一点:

当一个值存储在联合类型对象的成员中时,对象表示中不对应于该成员但对应于其他成员的字节采用未指定的值。

在这里,您使用联合类型的一个对象写入一个值,然后尝试访问该联合类型的另一个对象。这会导致您的类型出现不可预测的值。

因此,你不能做这样的事情。您应该只将联合的一个对象用于结构的同一实例。

于 2013-01-01T02:09:41.890 回答
1

正如@lbonn 所说,您正在滥用C!

-fms-extensions是一个 GCC 特定选项,它打开对非标准构造的支持,包括其他不可能的声明,例如您在上面尝试的那些。

简单的答案是:“不要那样做!” 严重地。不要使用-fms-extensions,尤其是不要用于您自己的代码!曾经!

编写符合标准 C 的声明有望使问题更容易被发现。

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.

于 2013-01-01T02:13:10.250 回答