加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

联合或结构是否允许从未初始化的实例进行分配?

发布时间:2020-12-16 10:08:20 所属栏目:百科 来源:网络整理
导读:这个问题是关于将未经初始化的自动变量分配给同一类型的另一个的定义或否则. 考虑 typedef struct{ int s1; int s2;} Foo;typedef union{ int u1; Foo u2; } Bar;int main(){ { int a; int b = a; // (1) } { Foo a; Foo b = a; // (2) } { Bar a; a.u1 = 0;
这个问题是关于将未经初始化的自动变量分配给同一类型的另一个的定义或否则.

考虑

typedef struct
{
    int s1;
    int s2;
} Foo;

typedef union
{
    int u1;
    Foo u2; 
} Bar;

int main()
{
    {
        int a;
        int b = a; // (1)
    }
    {
        Foo a;
        Foo b = a; // (2)
    }
    {   
        Bar a;
        a.u1 = 0;
        Bar b = a; // (3)
    }
}

参考主要评论:

(1)未定义,因为a未初始化.我知道的那么多.

但是(2)呢?结构成员s1和s2未初始化.

那么,(3)呢?内存u2.s2是未初始化的,所以读取它是未定义的行为吗?

解决方法

行为在(1)和(2)中未定义.

根据C标准,具有未初始化的自动存储持续时间的对象的值是不确定的(C 2011 [N1570] 6.7.9 10).名义上,这意味着它有一些价值,但我们不知道在编写程序时它是什么.

但是,该标准还说“如果左值指定了一个自动存储持续时间的对象,该对象可能已经使用寄存器存储类声明(从未使用过其地址),并且该对象未初始化(未使用初始化程序声明且未分配给它已在使用前执行),行为未定义“(6.3.2.1 2).在您的示例代码中,a的地址从未被采用,并且未被初始化,并且在表达式中使用它是左值.因此,行为未定义.

(本段6.3.2.1 2旨在容纳可以检测未初始化寄存器使用的处理器.但是,C标准中的规则适用于所有实现.)

(3)C标准没有明确说明.虽然为了6.3.2.1 2的目的,已经为联合的成员分配了一个值,因此没有未初始化,但是在b = a中使用的对象是联合,而不是其成员.显然,我们的直观概念是,如果为一个联合的成员分配了一个值,那么联合就有一个值.但是,我没有在C标准中看到这一点.

我们可以推断6.3.2.1 2不打算将联合或结构视为未初始化,至少如果它的一部分已被赋值,因为:

>结构可以包含未命名的成员,例如未命名的位字段.
>根据C 6.7.9 9,即使在初始化(结构)之后,未命名的结构成员也具有不确定的值.
>如果6.3.2.1 2适用于并非每个成员都分配了值的结构,那么如果a是具有未命名成员且具有自动存储持续时间的结构,则b = a将始终未定义.
>这似乎是不合理的,而不是标准的意图.

但是,这里有一些摆动空间.该标准可以指定,只有在初始化结构或其所有命名成员都已分配值时,结构才不是未初始化的.在这种情况下,如果a是仅为一个成员分配了值的结构,则(3)将是未定义的.我不认为这个摆动的房间存在于一个联盟;如果已为工会成员分配了一个值,则认为工会不是未初始化是合理的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读