结构零初始化方法

问题描述 投票:3回答:3

struct datainfo info = { 0 };

同样的

struct datainfo info;
memset(&info, 0, sizeof(info));

有什么区别,哪个更好?

c memset
3个回答
6
投票

第一个是国家英里的最佳方式,因为它保证struct成员初始化,因为它们将用于static存储。它也更清晰。

从标准的角度来看,无法保证这两种方式是等价的,尽管特定的编译器可以很好地优化第一种到第二种,即使它最终破坏了作为填充丢弃的部分内存。

(注意,在C ++中,第二种方式的行为很可能是未定义的。是C不是C ++,但是相当一部分C代码往往最终被移植到C ++。)


4
投票

实际上,这两种方法很可能产生相同的结果。可能是因为在今天的通用平台上首次编译成对memset本身的调用。

从语言律师的角度来看,第一种方法将零初始化结构的所有成员,但是没有任何关于任何填充字节可能采用的值的指定(在单个成员或结构中)。而第二种方法将所有字节清零。更准确地说,不能保证全字节零模式甚至是对象的“零”值。

因为(如果一个人知道他们的目标平台)这两个在程序员方面几乎相同,你选择最适合你喜好的那个。

就个人而言,我赞成通过调用memset进行初始化。因为它发生在声明点,而不是在另一个声明中,更不用说可移植性方面了。这使得不可能在两者之间意外地添加代码,这使得初始化不会运行(但不太可能),或者以某种方式出错。但有些人可能会说memset更清晰,甚至对程序员稍后阅读它并不知道{0}如何工作。我也不能完全无视他们的论点。


1
投票

正如其他人所指出的,代码是功能相同的。使用x86-64 gcc 8.3编译器

代码:

#include <string.h>
main()
{
    struct datainfo { int i; };
    struct datainfo info;

    memset(&info, 0, sizeof(info));
}

生产组件:

main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        lea     rax, [rbp-4]
        mov     edx, 4
        mov     esi, 0
        mov     rdi, rax
        call    memset
        mov     eax, 0
        leave
        ret

而代码:

main()
{
    struct datainfo { int i; };
    struct datainfo info = {0};
}

编译为:

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 0
        mov     eax, 0
        pop     rbp
        ret     

对于我未经训练的眼睛,两个输出是11个指令对6个指令,因此在第二个实现中至少空间更有效。但正如其他人所指出的,零初始化方法的意图要明确得多。

© www.soinside.com 2019 - 2024. All rights reserved.