gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 16:01:06 25 4
gpt4 key购买 nike

我最近在编译 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.x, test.y);
}

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

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

最佳答案

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

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 似乎确实在子对象初始化上建立了时间顺序,但此顺序并未以任何方式定义单个初始化器表达式的评估顺序。可以乱序计算初始化表达式。因此,它不能保证 test.y + 1.y = a 发生之后进行计算。这意味着您的示例确实未定义。

GCC 预计会产生警告

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

MSVC 报告

warning C4700: uninitialized local variable 'test' used

关于c - 在初始化中重新使用结构自己的成员是否可靠? (C99),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35491504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com