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