将 void 指针与 C 中的类型化指针进行比较(为了相等)是 UB 吗?
Is it UB to compare (for equality) a void pointer with a typed pointer in C?
我有一个类型化指针,typed
,它是使用指针算法初始化的,指向数组中的一个对象。我还有一个带有两个指针参数的函数,第一个与上述指针类型相同,第二个是 void *
(请参见下面代码中的 myfunc()
)。
如果我将 typed
作为第一个参数传递,并将另一个类型与 typed
相同的指针作为第二个参数传递,然后在函数内比较它们是否相等,是否为未定义行为?
#include <stdio.h>
typedef struct S {int i; float f;} s;
void myfunc(s * a, void * b)
{
if (a == b) // <-------------------------------- is this UB?
printf("the same\n");
}
int main()
{
s myarray[] = {{7, 7.0}, {3, 3.0}};
s * typed = myarray + 1;
myfunc(typed, &(myarray[0]));
return 0;
}
更新: 好的,所以我在上面发布我的问题一天后回来,有两个很好的答案(感谢@SouravGhosh 和@dbush)。一个比另一个早不到一分钟(!),但从第一个的评论来看,答案最初是错误的,直到第二个答案发布后才得到纠正。我接受哪一个?在这种情况下,是否有接受一个答案而不是另一个答案的协议?
这个比较定义明确。
当通过 ==
将 void *
与另一个指针类型进行比较时,另一个指针将转换为 void *
。
此外,C standard 的第 6.5.9p6 节说明了以下关于与 ==
的指针比较的内容:
Two pointers compare equal if and only if both are null pointers, both
are pointers to the same object (including a pointer to an object and
a subobject at its beginning) or function,both are pointers to one
past the last element of the same array object, or one is a pointer to
one past the end of one array object and the other is a pointer to the
start of a different array object that happens to immediately
follow the first array object in the address space.
这里没有提到未定义的行为。
不,这不是未定义的行为。这是允许的,并在相等运算符约束的规范中明确定义。引用 C11
,章节 6.5.9
one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void;
以及同一章第 5 段
[...] If one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void, the former is converted to the type of the latter.
我有一个类型化指针,typed
,它是使用指针算法初始化的,指向数组中的一个对象。我还有一个带有两个指针参数的函数,第一个与上述指针类型相同,第二个是 void *
(请参见下面代码中的 myfunc()
)。
如果我将 typed
作为第一个参数传递,并将另一个类型与 typed
相同的指针作为第二个参数传递,然后在函数内比较它们是否相等,是否为未定义行为?
#include <stdio.h>
typedef struct S {int i; float f;} s;
void myfunc(s * a, void * b)
{
if (a == b) // <-------------------------------- is this UB?
printf("the same\n");
}
int main()
{
s myarray[] = {{7, 7.0}, {3, 3.0}};
s * typed = myarray + 1;
myfunc(typed, &(myarray[0]));
return 0;
}
更新: 好的,所以我在上面发布我的问题一天后回来,有两个很好的答案(感谢@SouravGhosh 和@dbush)。一个比另一个早不到一分钟(!),但从第一个的评论来看,答案最初是错误的,直到第二个答案发布后才得到纠正。我接受哪一个?在这种情况下,是否有接受一个答案而不是另一个答案的协议?
这个比较定义明确。
当通过 ==
将 void *
与另一个指针类型进行比较时,另一个指针将转换为 void *
。
此外,C standard 的第 6.5.9p6 节说明了以下关于与 ==
的指针比较的内容:
Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function,both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.
这里没有提到未定义的行为。
不,这不是未定义的行为。这是允许的,并在相等运算符约束的规范中明确定义。引用 C11
,章节 6.5.9
one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void;
以及同一章第 5 段
[...] If one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void, the former is converted to the type of the latter.