11

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

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

总是返回零?

4

5 回答 5

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;
}
于 2013-05-29T13:48:15.583 回答
9

不,所有成员相等的两个结构有时可能不比较相等memcmp(),因为padding

一个似是而非的例子如下。对于 的初始化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
}
于 2013-05-29T13:47:44.230 回答
2

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

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

memset()如果在它们的成员被初始化为相同的值之前,两者都被初始化为某个共同的值,那么它们也将比较等于memcmp()(除非它们的成员也是结构,然后递归地应用相同的限制)。

于 2013-05-29T13:54:08.840 回答
2

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

当对象作为 type 的对象访问时,具有相同有效类型的对象可能具有相同的值 xy但 在其他上下文中具有不同的值。特别是,如果 为 type 定义,则并不意味着 。此外,并不一定意味着和具有相同的价值;对类型值的其他操作可能会区分它们。TT==Tx == ymemcmp(&x, &y, sizeof (T)) == 0x == yxyT

于 2013-05-30T10:07:36.027 回答
-1

如果您确保两个整个内存块在填充之前都已初始化,则可以保证它们是相同的,例如memset

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

编辑将其留在这里,因为评论流很有用。

于 2013-05-29T14:11:41.353 回答