如果我有两个C结构初始化为具有相同的成员,我可以保证:
memcmp(&struct1, &struct2, sizeof(my_struct))
总是会返回零?
答案 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)
如果两个变量都是全局变量或静态变量,并且它们的成员在程序的初始化时被初始化,那么是的,它们将与(注意,大多数系统只是将数据页加载到零初始化页面,但C标准不保证这种行为。)memcmp()
进行比较。
此外,如果其中一个结构使用memcpy()
与另一个结构初始化,那么它们将与memcmp()
进行比较。
如果在将成员初始化为相同值之前先将memset()
初始化为某个共同值,那么它们也将与memcmp()
进行比较(除非它们的成员也是结构,然后是相同的限制递归适用。)
答案 3 :(得分:2)
除了明显的struct padding情况之外,它甚至不能保证单个变量。见6.2.6.1(8)的脚注:
对象
x
和y
可能具有相同的有效类型T
在作为类型对象访问时具有相同的值T
,但在其他情境中有不同的值。特别是,如果==
是针对T
类型定义的,然后x == y
并不意味着memcmp(&x, &y, sizeof (T)) == 0
x == y
。此外,x
没有 必然意味着y
和T
具有相同的价值;其他 对{{1}}类型值的操作可以区分它们。
答案 4 :(得分:-1)
如果你确保在填充之前初始化了两个完整的内存块,你可以保证它们是相同的,例如:与 memset
:
memset(&struct1, 0, sizeof(my_struct))
编辑将此留在此处,因为评论信息流很有用。