【问题标题】:C struct padding on initialization初始化时的 C 结构填充
【发布时间】:2013-02-28 18:08:18
【问题描述】:

我有一个结构,例如

typedef struct
{
    int a;  // Let's say this ends up being 4 bytes
    int b;  // 4 bytes
    char text[10]; // 10 bytes
} blah_t;

static blah_t myvar;
  1. 假设blah_t中字段大小的总和为18字节,但sizeof(blah_t)由于填充而为20。
  2. myvar 是静态的,因此初始化为零。

问题:

  1. 对于静态变量,填充字节 19 和 20 是否保证为 0? 如果没有,我需要为结构的任何memcmp 执行memset(&myvar, 0, sizeof(blah_t)) 才能有效——即使对于静态变量也是如此。
  2. calloc(1, sizeof(blah_t)) 呢?字节 19 和 20 是否保证为零? 我相信是这样的。

【问题讨论】:

    标签: c struct padding calloc


    【解决方案1】:

    来自 ISO C99 标准:“当值存储在结构或联合类型的对象中时,包括在成员对象中,对应于任何填充字节的对象表示的字节采用未指定的值。”

    进一步看,这似乎讨论了一些其他问题: Comparing structures in C vs C++

    编辑:不是这个问题本身的重复,而是详细回答的许多常见问题。

    【讨论】:

    • 好引用标准;你能给出'章节和诗句'(哪个部分,哪个段落)?在 C2011 (ISO/IEC 9899:2011) 中,它位于 §6.2.6 Representations of types 和小节 §6.2.6.1 General, para 6。
    • 好点,我是故意的,把它留了。 6.2.6.1 类型的表示,第 6 段。
    • 我没有看到您提到的 C++ 问题有任何重复。 C++ 类是另一种动物。我希望找到什么......如果规范中的某个地方描述了如何针对这种特殊情况初始化静态变量。
    • 它明确表示填充值具有未指定的值,因此您不能真正相信 memcmp() 可移植地“做正确的事”。
    • 此答案可以针对 C11 更改进行更新。当静态变量未显式初始化时,填充位设置为零。我added an answer
    【解决方案2】:

    Randy Howard 接受的答案对于 C11 来说已经不太准确了。

    对于静态变量,填充字节 19 和 20 是否保证为 0?

    1. 在 C11 中,是的,当静态变量未显式初始化时,填充位设置为零。 C11 Standard,第 6.7.9 条第 10 段:

    。 . .如果具有 static 或线程存储持续时间的对象未初始化 明确地,那么: . . .如果它是一个聚合,则每个成员都会根据这些规则(递归地)初始化,并且任何填充都被初始化为零位。 . .

    1. 是的,calloc 会将结构的整个 sizeof(包括填充)归零。

    其他有用的相关链接:

    【讨论】:

      【解决方案3】:

      填充字节 19 和 20。对于静态,这些是否保证为 0 变量?

      请参阅兰迪霍华德的回答。

      那么 calloc(1, sizeof(blah_t) ) 呢?字节 19/20 是否保证 是零?

      是的。 calloc 将内存归零。

      出于好奇,我想知道您为什么关心填充。可移植代码不必担心表示的任何方面(填充、字节序等)。

      【讨论】:

      • 我想 memcmp 一个静态结构与一个通过 calloc 分配的结构。我知道在存储方面填充的行为是未定义的,但是静态分配的结构在规范中可能被认为是“存储”,也可能不被认为是“存储”。我正在寻找非常技术上的区别,是的。
      • 对可移植性没有影响,但对安全性很重要。填充未初始化的自动分配变量的信息可能会从堆栈中泄漏。
      猜你喜欢
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 2012-07-16
      相关资源
      最近更新 更多