C结构的内部一致性

时间:2013-05-29 13:44:48

标签: c struct memcmp

如果我有两个C结构初始化为具有相同的成员,我可以保证:

memcmp(&struct1, &struct2, sizeof(my_struct))

总是会返回零?

5 个答案:

答案 0 :(得分:10)

我认为你不能安全memcmp一个结构来测试平等。

来自C11 §6.2.6.6类型的表示

  

当值存储在结构或联合类型的对象中时,   包括在成员对象中,对象表示的字节   与任何填充字节对应的值都是未指定的值。

这意味着您需要编写一个比较结构的各个元素的函数

int my_struct_equals(my_struct* s1, my_struct* s2)
{
    if (s1->intval == s2->intval &&
        strcmp(s1->strval, s2->strval) == 0 && 
        s1->binlen == s2->binlen &&
        memcmp(s1->binval, s2->binval, s1->binlen) == 0 &&
        ...
        ) {
        return 1;
    }
    return 0;
}

答案 1 :(得分:9)

不,由于padding,所有成员相等的两个结构有时可能无法与memcmp()进行比较。

一个合理的例子如下。对于st2的初始化,符合标准的32位编译器可以生成一系列汇编指令,使最终填充的一部分保持未初始化状态。这段填充将包含堆栈中发生的任何内容,而st1的填充通常包含零:

struct S { short s1; long long i; short s2; } st1 = { 1, 2, 3 };
int main() {
  struct S st2 = { 1, 2, 3 };
  ... at this point memcmp(&st1, &st2, sizeof(struct S)) could plausibly be nonzero
}

答案 2 :(得分:2)

如果两个变量都是全局变量或静态变量,并且它们的成员在程序的初始化时被初始化,那么是的,它们将与memcmp()进行比较。(注意,大多数系统只是将数据页加载到零初始化页面,但C标准不保证这种行为。)

此外,如果其中一个结构使用memcpy()与另一个结构初始化,那么它们将与memcmp()进行比较。

如果在将成员初始化为相同值之前先将memset()初始化为某个共同值,那么它们也将与memcmp()进行比较(除非它们的成员也是结构,然后是相同的限制递归适用。)

答案 3 :(得分:2)

除了明显的struct padding情况之外,它甚至不能保证单个变量。见6.2.6.1(8)的脚注:

  

对象xy可能具有相同的有效类型   T在作为类型对象访问时具有相同的值   T,但在其他情境中有不同的值。特别是,如果   ==是针对T类型定义的,然后x == y并不意味着memcmp(&x, &y, sizeof (T)) == 0   x == y。此外,x没有   必然意味着yT具有相同的价值;其他   对{{1}}类型值的操作可以区分它们。

答案 4 :(得分:-1)

如果你确保在填充之前初始化了两个完整的内存块,你可以保证它们是相同的,例如:与memset

memset(&struct1, 0, sizeof(my_struct))

编辑将此留在此处,因为评论信息流很有用。