void * p ...; if(p> 0)....这是未定义的行为吗?

时间:2014-04-21 15:56:36

标签: c++ pointers

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

  

警告:指针与整数零[-Wextra]

的有序比较
    if (inx > 0)

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

一些研究表明:

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

带我到我原来的标准副本。

  

4.10指针转换

     

1空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零   或者类型为std :: nullptr_t的prvalue。空指针常量可以转换为指针类型;结果   是该类型的空指针值,并且可以与指向对象的指针的每个其他值区分开   指向函数类型的指针。这种转换称为空指针转换。两个空指针值   相同类型应相等。将空指针常量转换为指向cv-quali fi ed类型的指针是   单次转换,而不是指针转换的顺序,然后是定性转换(4.4)。   可以将整数类型的空指针常量转换为std :: nullptr_t类型的prvalue。

它明确指出两个空指针比较相等。

考虑到这一点,那段代码是不确定的行为?还是我还缺少另一块拼图?

2 个答案:

答案 0 :(得分:4)

它不是未定义的行为,但如果inx不为null,则结果未指定。

  

C ++ 11 5.9 / 2:如果同一类型的两个指针p和q指向不是同一个对象或同一个数组或不同函数的元素的不同对象,或者如果只是其中一个为空p<qp>qp<=qp>=q的结果未指定

因此,如果inx为空,您可以确定条件代码不会执行 - 但如果它不为空则不会执行。比较应该是inx != 0,当且仅当inx非空时才明确定义为真。

答案 1 :(得分:2)

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

具体而言,不指向相同数组或对象(的子对象)的指针之间的比较。

第5.9节第3和第4段,这个措辞可以在C ++ 14草案中找到。

  

比较指向对象的指针定义如下:

     
      
  • 如果两个指针指向同一个数组的不同元素或其子对象,则指向具有较高下标的元素的指针会比较大。
  •   
  • 如果一个指针指向一个数组的一个元素,或指向一个子对象,另一个指针指向一个超过该数组最后一个元素的指针,则后一个指针会比较大。
  •   
  • 如果两个指针指向同一个对象的不同非静态数据成员,或者指向这些成员的子对象,则递归地指向稍后声明的成员的指针比较更大,前提是两个成员具有相同的访问控制(第11条)如果他们的班级不是工会。
  •   
     

如果两个操作数pq比较相等(5.10),p<=qp>=q都会产生truep<q以及{{ 1}}都屈服   p>q。否则,如果指针false的比较大于指针p,则qp>=qp>qq<=p都会产生{{1} }}   q<ptruep<=qp<q都会产生q>=p否则,未指定每个运算符的结果。

在你的情况下,没有&#34;指针比大于&#34;关系是定义的,因此操作员根据他们的&#34;否则&#34;行为,给出未指明的结果。这种比较不会直接导致程序崩溃,但是假设q>p非空,它可以通过false进行分支。