无效 *p...;如果 (p > 0) ....这是未定义的行为吗?
void *p...; if (p > 0) .... Is this undefined behavior?
在编译器升级后,我遇到了一条新的警告消息。
警告:指针与整数零的有序比较[-Wextra]
if (inx > 0)
事实证明inx是一个指针。通常,我希望看到这个旧代码与0或NULL进行比较。这让我开始思考有符号和无符号的值,以及可能的风险。
一些研究表明:
- c++中大于零的指针是什么意思
- 指针(地址)可能是负数吗
- c中的内存地址正值或负值
- malloc返回负值
这些似乎表明地址(由malloc返回)永远不可能是零
这让我找到了我的旧标准。
4.10指针转换
1空指针常量是整数类型的整数常量表达式(5.19)prvalue,计算结果为零或std::nullptr_t类型的prvalue。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与指向对象或指向函数类型的指针。这种转换称为空指针转换。的两个空指针值同一类型比较应相同。将空指针常量转换为指向cv限定类型的指针是单个转换,而不是指针转换后的质量转换序列(4.4)。整型的空指针常量可以转换为std::nullptr_t类型的prvalue。
它特别指出两个空指针比较相等。
考虑到这一点,那一小段代码是未定义的行为吗?还是我还缺少另一块拼图
这不是未定义的行为,但如果inx
不为null,则未指定结果。
C++11 5.9/2:如果同一类型的两个指针p和q指向不同的对象,而这些对象不是同一对象的成员,或者不是同一数组的元素,或者指向不同的函数,或者如果其中只有一个为空,则
p<q
、p>q
、p<=q
和p>=q
的结果未指定。
因此,如果inx
为null,您可以确保条件代码不会执行,但如果它不为null,则不会执行。比较可能应该是inx != 0
,它被很好地定义为当且仅当inx
不为空时为真。
您关注的是指针转换,但应该关注指针比较。
特别是,不引用同一数组或对象(的子对象)的指针之间的比较。
第5.9节第3和第4段中的这一措辞见C++14草案。
比较指向对象的指针定义如下:
- 如果两个指针指向同一数组的不同元素或其子对象,则指向下标较高元素的指针比较大
- 如果一个指针指向数组的一个元素或其子对象,而另一个指针则指向数组最后一个元素之后的一个,则后一个指针比较大
- 如果两个指针递归地指向同一对象的不同非静态数据成员,或指向这些成员的子对象,则如果两个成员具有相同的访问控制权(第11条),并且它们的类不是并集,则指向后来声明的成员的指针比较大
如果两个操作数
p
和q
比较相等(5.10),则p<=q
和p>=q
都产生true
,p<q
和p>q
都产生CCD_ 16。否则,如果指针p
比较大于指针q
,则p>=q
、p>q
、q<=p
和q<p
都产生true
p<=q
、p<q
、q>=p
和q>p
均产生false
否则,每个运算符的结果都是未指定的
在你的情况下;指针比较大于"0";关系被定义,因此操作员根据他们的";否则";行为,给出未指明的结果。这种比较不会直接使程序崩溃,但它可以通过if
的任何一个分支,假设inx
不是null。
- 如果未定义的C++行为符合 C 定义的行为,会发生什么情况?
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- 根据下面的作者,如果两个指针指向不同的数组,则比较的第一个版本将未定义
- 如果没有未定义的行为 [c++],哪些浮点值无法转换为 int?
- 如果未使用方法本身,则忽略方法中的未定义符号
- 如果可能存在未定义行为,为什么编译器不警告您?
- C++:函数调用错误:标识符"name"未定义,如果已定义?
- 如果表达式的中间结果溢出,这是未定义的行为吗
- C++的 atoi() 如何保证如果它允许未定义的行为不会引发异常?
- 为什么有些事情在C++中留下了未定义的行为?如果其中一些在标准中预定义不是更好吗?
- 如果计数大于类型的宽度,则为右移未定义的行为
- 如果未定义选中的布尔宏,则生成错误
- 如果未定义赋值运算符,是否调用复制构造函数?
- 如果 cout 包含在我的标头中,为什么在我的 cpp 中未定义?
- 当函数在头文件中列出时,未定义的引用,但如果我直接复制和粘贴代码则没问题
- 如果未定义,如何获取PKEY_Device_FriendlyName
- 如果局部堆栈变量是未定义的行为,为什么编译器会发出有关返回对局部堆栈变量的引用的警告
- 如果使用未命名结构体或未定义标记实现不透明指针
- 如果一个过期的weak_ptr会给出未定义的行为,那么owner_less有什么意义呢
- 无效 *p...;如果 (p > 0) ....这是未定义的行为吗?