gpt4 book ai didi

有人可以解释这两个初始化程序之间的区别吗?

转载 作者:太空宇宙 更新时间:2023-11-04 00:00:53 26 4
gpt4 key购买 nike

我想知道是否有人可以对以下两段代码之间的差异提供详细、简单的解释。给定以下定义:

typedef struct {
stuff;
stuff_2;
} variable_t;

有什么区别:

  • variable_t my_variable;
  • variable_t my_variable = {};

如果我执行第一个,然后从未完全初始化它,为什么编译器不会抛出错误?

注意:我正在使用 gcc -std=gnu99 进行编译,所以第二个是有效的并且最终成为我遇到的问题的解决方案。我想知道为什么。

最佳答案

这在一定程度上取决于您放置相应变量定义的位置,而且似乎还取决于所使用的编译器。

自动存储时长

让我们讨论变量具有自动存储持续时间时的区别(如果将它放在函数或 block 作用域中并且没有 static 关键字就是这种情况):

void someFunction() {
variable_t my_variable; // (1)
variable_t my_variable = {}; // (2)
}

(1) 表示没有显式初始化的变量定义。并根据这个 online C standard draft ,它的值是不确定的:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

(2) 是一个变量定义,通过没有指示符的初始化列表进行显式初始化,即不通过名称将值与成员相关联,而仅通过值的顺序(参见 6.7.9 p17..21)。

有趣的段落是6.7.9 p21 , 它指出如果初始化列表的条目少于结构成员的数量,则根据静态存储持续时间的初始化规则(即 0NULL 稍后解释):

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, ... , the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

所以看起来,如果您编写 variable_t my_variable = {},那么所有成员都被初始化为 0NULL

但是,正如 aschepler 在评论中提到的那样,C initialization list grammar声明初始化列表不能为空(参见 cppreference.com ):

... the initializer must be a non-empty, brace-enclosed, comma-separated list of initializers for the members

所以根据标准,C 中的初始化列表至少需要一个条目;在我的 XCode8.3 环境中使用 -std=gnu99 测试它时,似乎支持一个空的初始化列表,但我知道这不是一个有效的引用。所以为了安全而不依赖于特定的编译器扩展,你实际上应该写:

   variable_t my_variable = {0};  

静态存储时长

在文件范围内,您的变量定义将具有静态存储持续时间,然后应用其他规则(参见 6.7.9 (10) ):

(10) ... If an object that has static or thread storage duration is not initialized explicitly, then:

  • if it has pointer type, it is initialized to a null pointer;
  • if it has arithmetic type, it is initialized to (positive or unsigned) zero;
  • if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
  • if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

...

(21) If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, ... the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

所以如果你写...

#include <stdio.h>
variable_t my_variable; // (1)
variable_t my_variable = {}; // (2)

那么 (1) 和 (2) 实际上会产生相同的结果,因为对于未显式初始化的变量 (1),段落 (10) 适用,而对于显式但为空的初始化变量 (2),根据段落 (21) ), 每个成员都退回到 (10) 的初始化规则。

同样,如上所述,编译器可能不支持空的初始化列表。

希望对您有所帮助(因为打了很多字:-))

关于有人可以解释这两个初始化程序之间的区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45019838/

26 4 0
文章推荐: c - 这些 C 指令在做什么,为什么要以这种方式构建这个库?
文章推荐: python - 枕头,添加和旋转图像中的文本
文章推荐: c - 如何将测量值发送到服务器并同时从传感器接收数据?
文章推荐: jquery - 在