我在编译器升级后遇到了一条新的警告消息。
警告:指针与整数零[-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。
它明确指出两个空指针比较相等。
考虑到这一点,那段代码是不确定的行为?还是我还缺少另一块拼图?
答案 0 :(得分:4)
它不是未定义的行为,但如果inx
不为null,则结果未指定。
C ++ 11 5.9 / 2:如果同一类型的两个指针p和q指向不是同一个对象或同一个数组或不同函数的元素的不同对象,或者如果只是其中一个为空,
p<q
,p>q
,p<=q
和p>=q
的结果未指定。
因此,如果inx
为空,您可以确定条件代码不会执行 - 但如果它不为空则不会执行。比较应该是inx != 0
,当且仅当inx
非空时才明确定义为真。
答案 1 :(得分:2)
您正在查看指针转换,但您应该查看指针比较。
具体而言,不指向相同数组或对象(的子对象)的指针之间的比较。
第5.9节第3和第4段,这个措辞可以在C ++ 14草案中找到。
比较指向对象的指针定义如下:
- 如果两个指针指向同一个数组的不同元素或其子对象,则指向具有较高下标的元素的指针会比较大。
- 如果一个指针指向一个数组的一个元素,或指向一个子对象,另一个指针指向一个超过该数组最后一个元素的指针,则后一个指针会比较大。
- 如果两个指针指向同一个对象的不同非静态数据成员,或者指向这些成员的子对象,则递归地指向稍后声明的成员的指针比较更大,前提是两个成员具有相同的访问控制(第11条)如果他们的班级不是工会。
如果两个操作数
p
和q
比较相等(5.10),p<=q
和p>=q
都会产生true
和p<q
以及{{ 1}}都屈服p>q
。否则,如果指针false
的比较大于指针p
,则q
,p>=q
,p>q
和q<=p
都会产生{{1} }}q<p
,true
,p<=q
和p<q
都会产生q>=p
。 否则,未指定每个运算符的结果。
在你的情况下,没有&#34;指针比大于&#34;关系是定义的,因此操作员根据他们的&#34;否则&#34;行为,给出未指明的结果。这种比较不会直接导致程序崩溃,但是假设q>p
非空,它可以通过false
进行分支。