微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我最近在编译C99代码时看到了一个警告,让我暂停询问这是否是未定义的行为.
(因为我构建在各种平台上,只有较旧的编译器版本显示此警告).

例如:

struct Vector { float x,y; };

void func(float a) {
    struct Vector test = { .x = a,.y = test.x + 1 };
    printf("%f %f\n",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 %f\n",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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐