如果传入空指针,以下代码是否安全?
if(ptr && *ptr == value)
{
//do something
}
检查的顺序重要吗?如果我把它改成这个,它会起作用吗?
if(*ptr == value && ptr)
{
//do something
}
如果传入空指针,以下代码是否安全?
if(ptr && *ptr == value)
{
//do something
}
检查的顺序重要吗?如果我把它改成这个,它会起作用吗?
if(*ptr == value && ptr)
{
//do something
}
前者是正确和安全的,后者不是。
内置&&
运算符具有短路语义,这意味着当且仅当第一个参数为真时才评估第二个参数。
(这不是重载运算符的情况。)
是 (1) 是安全的,因为短路。这是评估逻辑语句的方式。如果陈述的第一部分&&
为假,那么整个陈述永远不会为真,因此它不会尝试评估第二部分。
(2) 是不安全的,因为它首先取消引用空指针,这是未定义的行为。
编辑:
参考下面的 KerrekSBs 评论: 为什么取消引用空指针是未定义的行为?
从该帖子中的第一个答案:
为取消引用 NULL 指针定义一致的行为将要求编译器在大多数 CPU 架构上的每次取消引用之前检查 NULL 指针。对于为速度而设计的语言来说,这是一个不可接受的负担。
还有(历史上)硬件,其中NULL
(并非总是 0
)指向的内存实际上在程序中是可寻址的,并且可以取消引用。因此,由于缺乏共识和一致性,决定取消引用空指针将是“未定义的行为”
如果指针无效(或者更确切地说NULL
,正如所指出的那样),在第一个版本中,短路将阻止对 的评估*ptr == value
,因此第一个是安全的。
第二个将始终访问*ptr
,无论它是否有效。
除了所有其他关于ptr && *ptr == value
有效但不是相反的答案之外,有效指针的概念可能具有不同的含义。
可以是未初始化的变量,或者可以以不指向任何地方(例如悬空指针)但不为空的方式ptr
获得(例如,通过某个随机整数的强制转换)。intptr_t
在这种情况下,测试顺序都不起作用。
一些指针可能是无效的并且是非空的(那么测试ptr && *ptr == value
就是未定义的行为)。没有可移植的方法来测试它们。(但您可以使用操作系统或处理器特定的技巧)。