11

如果传入空指针,以下代码是否安全?

if(ptr && *ptr == value)
{
   //do something
}

检查的顺序重要吗?如果我把它改成这个,它会起作用吗?

if(*ptr == value && ptr)
{
   //do something
}
4

4 回答 4

20

前者是正确和安全的,后者不是。

内置&&运算符具有短路语义,这意味着当且仅当第一个参数为真时才评估第二个参数。

(这不是重载运算符的情况。)

于 2012-12-08T22:36:11.203 回答
3

是 (1) 是安全的,因为短路。这是评估逻辑语句的方式。如果陈述的第一部分&&为假,那么整个陈述永远不会为真,因此它不会尝试评估第二部分。

(2) 是不安全的,因为它首先取消引用空指针,这是未定义的行为。

编辑:

参考下面的 KerrekSBs 评论: 为什么取消引用空指针是未定义的行为?

从该帖子中的第一个答案:

为取消引用 NULL 指针定义一致的行为将要求编译器在大多数 CPU 架构上的每次取消引用之前检查 NULL 指针。对于为速度而设计的语言来说,这是一个不可接受的负担。

还有(历史上)硬件,其中NULL(并非总是 0)指向的内存实际上在程序中是可寻址的,并且可以取消引用。因此,由于缺乏共识和一致性,决定取消引用空指针将是“未定义的行为”

于 2012-12-08T22:36:02.083 回答
1

如果指针无效(或者更确切地说NULL,正如所指出的那样),在第一个版本中,短路将阻止对 的评估*ptr == value,因此第一个是安全的。

第二个将始终访问*ptr,无论它是否有效。

于 2012-12-08T22:36:01.973 回答
1

除了所有其他关于ptr && *ptr == value有效但不是相反的答案之外,有效指针的概念可能具有不同的含义。

可以是未初始化的变量,或者可以以不指向任何地方(例如悬空指针)但不为空的方式ptr获得(例如,通过某个随机整数的强制转换)。intptr_t

在这种情况下,测试顺序都不起作用。

一些指针可能是无效的并且是非空的(那么测试ptr && *ptr == value就是未定义的行为)。没有可移植的方法来测试它们。(但您可以使用操作系统或处理器特定的技巧)。

于 2012-12-08T22:41:54.437 回答