通过“myPtr > 0”检查空指针

ucc*_*czs 33 c++ comparison null null-pointer null-check

在一些遗留代码中,我遇到了以下空指针检查

if( myPtr > 0 ) {
...
}
Run Code Online (Sandbox Code Playgroud)

通过此 if 检查检查空指针是否存在任何技术风险?

eer*_*ika 39

在 C++ 中,指针和整数之间的有序比较是错误的(即使整数是空指针常量,如本例所示)。风险在于编译器被允许并且确实拒绝编译此类代码。


您可以将其重写为以下任一形式:

if(myPtr != nullptr)
if(myPtr)
Run Code Online (Sandbox Code Playgroud)

  • @AyxanHaqverdili 不过,没有“-迂腐错误”。一些编译器(包括 GCC)默认接受一些格式错误的程序。 (16认同)
  • 旁注,它确实编译为 C 代码 https://godbolt.org/z/qjvs77W3b (3认同)

Yak*_*ont 19

0是一个 NULL 常量。所以这相当于ptr > (void*)0.

问题是>C++ 中的 on 指针仅对指向同一对象或数组的指针有效。这个规则起源于当时分段内存等相对疯狂的东西更常见的时候,但它允许编译器进行优化和假设。

例如,假设px是一个指向数组的指针,它当前指向第一个元素。thenpx>py为 true,除非py也是指向第一个元素的指针。或者,如果px是指向数组末尾一位的指针,则px<py始终为 false。

使用这种知识,编译器可以理解重构和重写循环边界,这反过来又可以让编译器生成更快的代码。

但这也意味着这px>py可能在一个地方是正确的,而在另一个地方却不是,因为编译器可以在一个地方证明一个事实,py但在另一个地方却不能。

简而言之,在指针比较时要非常小心。

同时,null 和任何其他指针之间的相等性是明确定义的。

std::less保证行为良好,并同意<何时<定义;这允许指针映射工作。

在这种情况下,正确的重写是:

if(myPtr!=nullptr)
Run Code Online (Sandbox Code Playgroud)

myPtr如果不是指针,则编译失败,或者

if(myPtr)
Run Code Online (Sandbox Code Playgroud)

myPtr如果是有符号数字类型,则存在您刚刚更改行为的风险。我会做第一个。

  • _这条规则起源于当时分段内存等相对疯狂的东西更常见的时候_ =&gt; 值得注意的是,像 CHERI 这样的现代架构是“有效”的段,比较不同来源的指针可能最终会触发错误。 (4认同)