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

在初始化中重新使用结构自己的成员是否可靠? (C99)

发布时间:2020-12-16 10:01:47 所属栏目:百科 来源:网络整理
导读:我最近在编译C99代码时看到了一个警告,让我暂停询问这是否是未定义的行为. (因为我构建在各种平台上,只有较旧的编译器版本显示此警告). 例如: struct Vector { float x,y; };void func(float a) { struct Vector test = { .x = a,.y = test.x + 1 }; printf
我最近在编译C99代码时看到了一个警告,让我暂停询问这是否是未定义的行为.
(因为我构建在各种平台上,只有较旧的编译器版本显示此警告).

例如:

struct Vector { float x,y; };

void func(float a) {
    struct Vector test = { .x = a,.y = test.x + 1 };
    printf("%f %fn",test.x,test.y);
}

使用Clang 3.9.0和GCC5.3(在Linux上),代码可以在没有警告的情况下编译.
但是对于Clang 3.4.1(在FreeBSD上),我收到以下警告.

test.c:74:21: warning: variable 'test' is uninitialized when used within its own initialization [-Wuninitialized]
    .y = test.x + 1
     ^~~~

上面的代码应该相当于:

void func(float a) {
    struct Vector test;
    test.x = a;
    test.y = test.x + 1;
    printf("%f %fn",test.y);
}

它可能在一个编译器中工作但仍然是未定义的行为,所以我的问题是:

提供初始化顺序在使用前分配成员.
C99结构初始化是否重用成员并保证可预测的结果?

解决方法

在这种情况下,自引用初始化的正确语法是

struct Vector test = { .y = a,.x = test.y + 1 };

现在,语言规范说

6.7.9 Initialization

23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.

虽然6.7.9 / 19似乎确实在子对象初始化上建立了时间顺序,但这种排序不以任何方式定义单个初始化表达式的评估顺序.可以不按顺序评估初始化表达式.因此,它不能保证在.y = a之后评估test.y 1.这意味着您的示例确实未定义.

海湾合作委员会预计会发出警告

'test.y' is used uninitialized in this function [-Wuninitialized]

MSVC报道

warning C4700: uninitialized local variable 'test' used

(编辑:李大同)

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

    推荐文章
      热点阅读