在移植的c头中NULL与nullptr

NULL vs nullptr in a ported c header

本文关键字:NULL nullptr 头中      更新时间:2023-10-16

我在代码中使用std::getenv调用,我不确定这三个选项-

const char *env_p = std::getenv("SOME_ENV");
if(env_p == NULL){
    std::cout << "NULL caught";
}
if(env_p == 0){
    std::cout << "0 caught";
}
if(env_p == nullptr){
    std::cout <<"nullptr caught";
}

我应该用哪一个?我更倾向于nullptr版本,因为c++推荐它,但由于cstdlib最初是一个c头,我不确定要检查NULL0nullptr

我运行了一个程序进行检查,三个变量都被捕获了,因为并没有一个具有上述名称的env变量。所以这让我可以选择使用它们中的任何一个,甚至if(!env_p),对吧?

但我不太确定,因为这可能只适用于这个例子,或者依赖于机器,或者我可能缺少的东西。那么有人能证实这个案子吗?

感谢

在您的案例中,它们都是一样的。空指针是一个具有神奇值的指针,它与任何指向实际数据的指针都不匹配。通常,我们认为它是地址0,大多数实现实际上使用地址0来表示空指针,但这是一个实现细节。

if (env_p == 0)

将此文字0与指针进行比较,因此编译器会将其转换为指针。文字零转换为指针会导致空指针,因为标准是这么说的

if (env_p == NULL)

这实际上是一样的,因为在几乎所有的实现中,NULL都是定义为0的宏。(有一段时间,C将NULL定义为(void*)0并不罕见,但由于这里不重要的原因,这已经不流行了。)

if (env_p == nullptr)

nullptr是一个C++关键字,它为您提供了一个特殊类型的空指针。但它仍然只是一个空指针,所以它完全按照您的意愿执行。

在C++中有一些情况(如完美转发),您必须使用nullptr而不是NULL0来保证您有一个空指针(而不是碰巧为0的int),以确保类型推导选择写入模板实例化或重载。

最后,检查指针的常见习惯用法是:

if (env_p) { ... } // true if not a null pointer
if (!env_p) { ... } // true if a null pointer

这之所以有效,是因为不等式与0有一个隐含的比较。也就是说,他们被完全像你写的那样对待:

if ((env_p) != 0) { ... }
if ((!env_p) != 0) { ... }

因此,它之所以有效,是因为上述原因。

在C++中,我使用nullptr作为空指针。在C语言或可以以任何一种模式编译的代码中,我通常使用NULL,因为它比使用0更清晰。

简短回答:它们都是一样的,可以互换使用。

稍长的答案:

std::getenv在失败时返回NULL指针:

标识环境变量的值的字符串,如果找不到空指针

如果你想检查功能是否失败,你可以使用以下任意一种:

  • if (env_p == NULL)定义为0#define NULL 0
  • if (env_p == 0)是一样的
  • if (env_p == nullptr)是一种C++安全的方法(只能与指针进行比较)
  • env_pfalse时,if (!env_p)仅为true,因此与检查env_p == 0相同

如果你使用的是现代C++,我会坚持使用nullptr