C++ void*p。。。;如果(p>;0)。。。。这是未定义的行为吗?

C++ void*p。。。;如果(p>;0)。。。。这是未定义的行为吗?,c++,pointers,C++,Pointers,在编译器升级后,我遇到了一条新的警告消息 警告:指针与整数零[-Wextra]的有序比较 if (inx > 0) 事实证明,inx是一个指针。通常,我希望看到这段旧代码与0或NULL进行比较。这让我想到了有符号和无符号的值,以及可能的风险 一些研究表明: 这些似乎表明地址(由malloc返回)永远不能为零 这让我找到了我的旧标准 4.10指针转换 1空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零 或std::nullptr\t类型的p

在编译器升级后,我遇到了一条新的警告消息

警告:指针与整数零[-Wextra]的有序比较

    if (inx > 0)
事实证明,inx是一个指针。通常,我希望看到这段旧代码与0或NULL进行比较。这让我想到了有符号和无符号的值,以及可能的风险

一些研究表明:

这些似乎表明地址(由malloc返回)永远不能为零

这让我找到了我的旧标准

4.10指针转换

1空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零 或std::nullptr\t类型的prvalue。空指针常量可以转换为指针类型;结果 是该类型的空指针值,可与指向对象或 指向函数类型的指针。这种转换称为空指针转换。的两个空指针值 同一类型应比较相同。将空指针常量转换为cv限定类型的指针是 一次转换,而不是指针转换后的合格转换序列(4.4)。 整数类型的空指针常量可以转换为std::nullptr\t类型的prvalue

它特别声明两个空指针比较相等


考虑到这一点,这段代码是否有未定义的行为?或者我还缺少另一块拼图?

这不是未定义的行为,但如果
inx
不为空,则结果是未指定的

C++11 5.9/2:如果同一类型的两个指针p和q指向不属于同一对象或同一数组元素或不同函数的不同对象,或者如果只有一个指针为null,则
pq
p=q
的结果是未指定的


因此,您可以确定,如果
inx
为null,条件代码将不会执行,但如果不为null,则不会执行。比较可能应该是
inx!=0
,当且仅当
inx
为非null时,该值定义为true。

您正在查看指针转换,但应该查看指针比较

具体来说,是指不引用同一数组或对象的(子对象)的指针之间的比较

第5.9节第3段和第4段中,C++14草稿中有此措辞

将指针与对象进行比较定义如下:

  • 如果两个指针指向同一数组的不同元素或其子对象,则指向下标较高的元素的指针比较大
  • 如果一个指针指向数组的一个元素或其子对象,而另一个指针指向数组最后一个元素的另一个指针,则后一个指针比较大
  • 如果两个指针递归地指向同一对象的不同非静态数据成员,或指向此类成员的子对象,则如果两个成员具有相同的访问控制(第11条)且其类不是并集,则指向后一个声明成员的指针会比较大
如果两个操作数
p
q
比较相等(5.10),
p=q
都产生
true
pq
都产生
false
。否则,如果指针
p
比较大于指针
q
p>=q
p>q
q如果(inx==0)
,编译器会告诉你什么?部分问题是源代码中的
0
表示空指针。但是,空指针不能作为0存储在内存中。它可以是0xFFFFFFFFFFFFFF或任何其他值。由于NULL的实际值未指定,因此所有与它的比较也未指定。@BenVoigt:我直接从我的C++11副本中复制了它。n3690和n3797都有我引用的措辞。“那些草稿不包括C++11吗?”本沃伊特:我不知道;我只是引用了已经发布的标准。@BenVoigt:根据我的说法,你的两个草稿都是后C++11版本。这个措辞出现在草案n3290中。@Mat:ah,谢谢。Mike的措辞也在n3485中。很好,我们现在已经涵盖了C++03和C++11(在迈克的回答中)以及C++14。