检查指针是否为null,然后在同一if语句中取消引用它,这样安全吗

Is it safe to check if a pointer is null, then dereference it in the same if statement?

本文关键字:引用 取消 安全 语句 是否 指针 null 然后 检查 if      更新时间:2023-10-16

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

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

支票的顺序重要吗?如果我把它改成这个行吗?

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

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

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

(过载操作员的情况并非如此。)

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

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

编辑:

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

来自该帖子的第一个答案:

定义取消引用NULL指针的一致行为将要求编译器在每个对大多数CPU架构的取消引用。这是不可接受的burdern为一种专为速度而设计的语言。

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

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

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

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

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

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

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