gpt4 book ai didi

静态数组的条件初始化,使用复合文字

转载 作者:行者123 更新时间:2023-12-05 01:52:43 24 4
gpt4 key购买 nike

#include <stdint.h>

#define INIT_UINT32 1
#define INIT_INT32 2

#define INIT INIT_INT32

typedef union
{
uint32_t a;
int32_t b;
} Foo_t;

/* Why does this compile... */
static Foo_t foo_static = INIT == INIT_INT32 ?
(Foo_t){ .a = UINT32_MAX} : (Foo_t){ .b = INT32_MAX };

/* but this doesn't? */
static Foo_t foo_static_array[] =
{
INIT == INIT_INT32 ? (Foo_t){ .a = UINT32_MAX} : (Foo_t){ .b = INT32_MAX }
};

int main(void)
{
}

编译时,使用复合字面量的 foo_static 条件初始化成功,但使用复合字面量的 foo_static_array 条件初始化失败。以下是编译错误。

$ gcc test.c
test.c:4:21: error: initializer element is not constant
4 | #define INIT_INT32 2
| ^
test.c:6:14: note: in expansion of macro ‘INIT_INT32’
6 | #define INIT INIT_INT32
| ^~~~~~~~~~
test.c:21:3: note: in expansion of macro ‘INIT’
21 | INIT == INIT_INT32 ? (Foo_t){ .a = UINT32_MAX} : (Foo_t){ .b = INT32_MAX }
| ^~~~
test.c:4:21: note: (near initialization for ‘foo_static_array[0]’)
4 | #define INIT_INT32 2
| ^
test.c:6:14: note: in expansion of macro ‘INIT_INT32’
6 | #define INIT INIT_INT32
| ^~~~~~~~~~
test.c:21:3: note: in expansion of macro ‘INIT’
21 | INIT == INIT_INT32 ? (Foo_t){ .a = UINT32_MAX} : (Foo_t){ .b = INT32_MAX }
| ^~~~

谁能解释一下为什么会这样?

最佳答案

GCC 提供前者初始化作为 C 标准的扩展。它没有提供后者。这是 GCC 的选择,不是标准强制要求的。对于 -pedantic,GCC 会提示这两者。

C标准中的相关段落是C 2018 6.7.9 4:

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

这是在 Constraints 部分,这意味着符合标准的编译器必须诊断它,就像 GCC 在使用 -pedantic 时所做的那样,尽管它仍然接受代码并完成编译。没有 -pedantic,GCC 接受两者但只诊断后者。

关于 C 扩展的 GCC 文档没有说明这种差异的原因。它的clause 6.27说具有自动存储持续时间的聚合的初始值设定项不需要是常量表达式,但 C 扩展子句中没有子条款解决静态对象的初始值设定项。

为了使您的代码严格符合规范,您不应在非数组或数组初始化中使用这些初始化器。

关于静态数组的条件初始化,使用复合文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71516207/

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