我可以使用 memcmp 检查结构中的非零成员吗?

Can I use memcmp to check struct for non-zero members?

我正在使用一个包含许多成员的大型结构,我想要一种简单的方法来快速查看是否有任何成员非零。我知道 memcmp() 不应该用于比较两个结构是否相等(如此处解释:How do you compare structs for equality in C?),但我希望通过将结构与已设置为 0 的内存块进行比较,这可能有效。

例如,假设我有一些结构:

typedef struct {
    int Int1;
    int Int2;
    int Int3;
} MyInts;

我从这个结构创建了一个变量:

MyInts MyStruct = {0};

在我的程序的整个执行过程中,MyStruct 的成员通常为 0,但有时可能会临时设置为一些非零值。我想快速检查 MyStruct 中的任何整数是否非零。我可以像下面那样使用 memcmp() 吗?

// Create empty struct to test against
MyInts EmptyStruct = {0};

// Make sure entire memory block of test struct is cleared
memset(&EmptyStruct, 0, sizeof(MyInts));

// Compare MyStruct to EmptyStruct to see if any non-zero members exist
int result = memcmp(&MyStruct, &EmptyStruct, sizeof(MyInts));

在一般情况下您不能这样做,因为结构可以在字段之间和结构的末尾进行填充,并且不能保证填充字节的内容(可能是未初始化的垃圾)。

如果两个被比较的结构最初分配了calloc,或者sizeof(thestruct)字节memset在填充实际之前为零值,那么填充将具有可预测的值,并且 memcmp 将起作用。同样,如果你能保证没有填充,那么这个 memcmp 就可以了。但是,如果其中之一可能没有被归零,不,不安全。

当然,如果你想成为 "nice",你可以直接比较成员,可能在分解函数中,让编译器处理优化,而不用担心你是否有带填充的未清零结构飘来飘去。

注意:您提供的 link 中的 The second highest voted answer 涵盖了这一点。对该答案的评论还指出了一些边缘情况,例如floats 可以具有比较相等但具有不同位表示的值,因此即使如此它也不能推广到所有结构。

为了清楚起见,我决定继续并根据评论回答我自己的问题。正如@M.M 提到的,填充不能保证被结构赋值保留,也可能不会被单个成员赋值保留。因此,使用 memcmp 检查非零成员的结构是不安全的。

那样,安全的做法是单独比较每个结构成员。