Mar*_* Ba 14 c++ comparison void-pointers language-lawyer
Run Code Online (Sandbox Code Playgroud)... 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) ...
如果完全定义使用C++的行为(根据03或11个标准),以我想知道比较的(中)相等对两个空指针指向有效的,但不同的对象.
更一般地说,但可能不那么相关,是比较(==或!=)两个void*总是定义的类型的值,还是要求它们持有指向有效对象/存储区域的指针?
Kos*_*Kos 12
C说:
两个指针比较相等,当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针和开头的子对象)或函数,两者都是指向同一数组的最后一个元素的指针对象,或者一个是指向一个数组对象末尾的指针,另一个是指向不同数组对象的开头的指针,该对象恰好跟随地址空间中的第一个数组对象.
C++说:
相同类型的两个指针比较相等,当且仅当它们都为空时,都指向相同的函数,或者两者都表示相同的地址.
因此,这意味着:
一个)
它是C++中完全定义的行为(根据03或11标准)来比较两个指向有效但不同对象的(in)相等的void指针.
所以是的,在C和C++中.您可以比较它们,在这种情况下,如果它们指向同一个对象,它们将比较为真.这很简单.
b)
是比较(==或!=)两个类型为void*总是定义的值,还是要求它们持有指向有效对象/内存区域的指针?
同样,比较是明确定义的(标准说"当且仅当"因此两个指针的每个比较都是明确定义的).但是之后...
这太令人惊讶了!
的确,这不是GCC的工作方式:
int main() {
void* a = (void*)1; // misaligned, can't point to a valid object
void* b = a;
printf((a == b) ? "equal" : "not equal");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果:
equal
Run Code Online (Sandbox Code Playgroud)
也许在C中的UB有一个不是空指针的指针,并且没有指向一个对象,子对象或一个超过数组中最后一个对象的指针?嗯...这是我的猜测,但后来我们有了:
整数可以转换为anypointer类型.除了之前指定的,结果是实现定义,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示.
所以我只能解释它上面的程序定义明确,C标准期望它打印"不相等",而GCC并没有真正服从标准,而是提供了更直观的结果.