c - 在使用之前对结构进行 memset 是一种很好的风格吗?

标签 c linux signals

一旦我学会了信号,就会有一个处理信号的 list 。

有一个 struct sigaction,它是第一个 memset() 到所有字节为零的以下行:

memset(&sa, 0, sizeof(sa));

而且我不确定作者为什么使用这种方法。

最佳答案

如前所述,尝试从结构的未初始化成员中读取值会导致未定义的行为。那是无条件的坏。因此,您有责任确保所有字段在读取之前都已初始化。

如果您知道结构的所有元素并打算显式初始化它们,则不需要 memset()。如果结构在您的控制之下,这是可管理的——您只需要记住确保在向结构添加新成员时更新所有初始化发生的地方。如果您编写一个函数来执行此操作(想想“C++ 构造函数的 C 模拟”,初步近似),则可以省略 memset()。如果您在许多地方临时设置值,那么如果结构发生变化,您可能会遇到问题。

在类似 struct sigaction 的情况下,它来自系统定义的 header ,不同的系统可以(并且确实)向结构添加额外的字段——超出您计划的字段初始化。请注意,POSIX 仅指定必须存在的字段;它不规定字段的顺序,也不强制结构中没有其他字段。但是,使用结构的额外(非 POSIX)元素的函数不应该这样做,除非用户指示这些成员已初始化,通常带有一些显式标志,所以你不应该遇到问题 - 但它更安全比抱歉。

因此,在您无法控制结构的上下文中,memset() 方法很容易防御:它保证将所有结构归零,甚至是您不想要的位不知道 — 即使结构定义在编写代码后发生变化(增长)。

您可以使用 struct sigaction sa = { 0 };struct sigaction *sap = calloc(sizeof(*sap), 1); 归零相反,结构 — 它部分取决于您使用的一组编译器选项的挑剔程度(以及您使用的编译器版本;例如,GCC 随着时间的推移改变了它的行为)。

您可能想要查找 POSIX 标准中的宏,例如 PTHREAD_MUTEX_INITIALIZER — 或者您可能更愿意完全忽略它们的存在。

关于c - 在使用之前对结构进行 memset 是一种很好的风格吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37105736/

相关文章:

linux - 如何在 linux 系统上搜索包含文本字符串的文本文件

linux - 如何在 Makefile 中捕获退出 (ctrl+c) 信号?

c 编程 - 无法获得所需的输出

c++ - C/C++ 中的非线程安全文件 I/O

linux - 如何将多个文件下载、解压并直接传输到一个 s3 存储桶中?

python - Django:断开 post_save 信号以避免递归

C 无法在 `sigsuspend` 之后向子进程发出继续操作信号

c - 为什么我的内核的共享内存似乎被初始化为零?

c - MSP430 的 CCS 中出现错误 : Expected an identifier,

javascript - 如何使用 node.js 获取系统统计信息