是否比较两个 void 指针到 C++ 中定义的不同对象?
受到关于动态转换为 void*
的这个答案的启发:
<前><代码>... 布尔 eqdc(B* b1, B *b2) { 返回dynamic_cast(b1)==dynamic_cast (b2); } ... int main() { DD *dd = 新的 DD(); D1 *d1 =dynamic_cast (dd); D2*d2=dynamic_cast (dd); ... eqdc(d1, d2) ...
我想知道比较两个指向有效的空指针是否相等是否是C++中完全定义的行为(根据03或11标准),但是不同的对象。
更一般地说,但可能不那么相关,比较(==
或!=
)始终定义的 void*
类型的两个值,或者是它要求它们持有指向有效对象/内存区域的指针?
Inspired by this answer about dynamic cast to void*
:
... bool eqdc(B* b1, B *b2) { return dynamic_cast<void*>(b1) == dynamic_cast<void*>(b2); } ... int main() { DD *dd = new DD(); D1 *d1 = dynamic_cast<D1*>(dd); D2 *d2 = dynamic_cast<D2*>(dd); ... eqdc(d1, d2) ...
I am wondering if it is fully defined behaviour in C++ (according to the 03 or 11 standard) to compare two void pointers for (in)equality that point to valid, but different objects.
More generally, but possibly not as relevant, is comparing (==
or !=
) two values of type void*
always defined, or is it required that they hold a pointer to a valid object/memory area?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
C 说:
C++ 说:
因此,这意味着:
a)
所以是的,在 C 和 C++ 中都是如此。您可以比较它们,在这种情况下,当它们指向同一对象时,它们将比较为 true。这很简单。
b)
同样,比较是明确定义的(标准说“当且仅当”,因此两个指针的每次比较都是明确定义的)。但是...
这太令人惊讶了!
事实上,这不是 GCC 的工作方式:
结果:
也许 C 中的 UB 拥有一个不是空指针的指针并且不指向一个对象、子对象或数组中最后一个对象之后的对象?嗯...这是我的猜测,但我们有:
所以我只能解释为上面的程序定义良好,C标准期望它打印“不等于”,而GCC并没有真正遵守标准,但给出了更直观的结果。
C says:
C++ says:
Hence it would mean that:
a)
So yes, in both C and C++. You can compare them and in this case they shall compare as true iff they point to the same object. That's simple.
b)
Again, the comparison is well-defined (standard says "if and only if" so every comparison of two pointers is well-defined). But then...
This is surprising!
Indeed that's not how GCC works:
result:
Maybe it's UB in C to have a pointer which isn't a null pointer and doesn't point to an object, subobject or one past the last object in an array? Hm... This was my guess, but then we have that:
So I can only interpret it that the above program is well-defined and the C standard expects it to print "not equal", while GCC doesn't really obey the standard but gives a more intuitive result.
C++11、5.10/1:
所以是的,具体比较就可以了。
一般来说,尝试创建不是有效地址的指针值是未定义的行为 - 例如使用指针算术在数组的开头之前或末尾之后 - 更不用说使用它们了。像
(void*)23
这样的结果是实现定义的,因此除非实现具有特定权限,否则比较这些内容实际上也是未定义的行为,因为实现可能会定义结果是void*
的陷阱值。C++11, 5.10/1:
So yes, the specific comparison is OK.
In general it is undefined behavior to attempt to create a pointer value that isn't a valid address - for example using pointer arithmetic to go before the beginning or after the one-after-the-end of an array - let alone use them. The result of stuff like
(void*)23
is implementation-defined, so barring specific permission from the implementation it is in effect undefined behavior to compare those too, since the implementation might define that the result is a trap value ofvoid*
.