【问题标题】:Struct zero initialization methods结构零初始化方法
【发布时间】:2023-03-11 12:08:01
【问题描述】:

struct datainfo info = { 0 };

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

有什么区别,哪个更好?

【问题讨论】:

标签: c memset


【解决方案1】:

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

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

(请注意,在 C++ 中,第二种方式的行为很可能是未定义。是的,C 不是 C++,但相当多的 C 代码确实倾向于最终被移植到 C++。)

【讨论】:

  • 说实话,也许只是我的 C++ 程序员在说话,但我发现 {}{0} 形式更清晰。可惜 C 不接受第一种形式(没有 GNU 扩展)。
  • @StoryTeller:确实,我想知道为什么 C 还没有{}?但我远非 C 专家。也许他们有他们的理由?
  • 希望我知道,因为这是我总是绊倒我的一件事。
【解决方案2】:

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

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

由于(如果知道他们的目标平台)这两者在程序员的每一个方面都几乎相同,因此您可以选择最适合您偏好的一个。

就个人而言,我更喜欢初始化而不是调用memset。因为它发生在声明时,而不是在另一个声明中,更不用说可移植性方面了。这使得不可能在两者之间意外添加导致初始化无法运行的代码(尽管这不太可能),或者以某种方式出现故障。但是有些人可能会说memset 更清晰,即使对于后来阅读它的程序员也不知道{0} 是如何工作的。我也不能完全无视他们的论点。

【讨论】:

    【解决方案3】:

    正如其他人所指出的,代码是功能等效的。 使用 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 条指令,因此在第二个实现中至少空间更有效。但正如其他人所指出的,零初始化方法的意图要明确得多。

    【讨论】:

    • 您是否在打开优化的情况下编译了代码?以固定的小尺寸调用memset 应该是优化器的牺牲品,
    • @harper 没有启用编译器选项。如果您有兴趣尝试各种编译器的编译输出,可以在这里在线试用:godbolt.org
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    相关资源
    最近更新 更多