【问题标题】:C++: Compare return value of C function to NULL or nullptr?C ++:将C函数的返回值与NULL或nullptr进行比较?
【发布时间】:2014-10-28 07:47:07
【问题描述】:

我正在用 C++ 编写代码,并使用一个在失败时返回 NULL 的 C 函数。正确的做法是什么,将其返回值与 NULL 或 nullptr 进行比较?

if ((CreateEventEx(myEventHandleHere) == NULL)
{
    ...
}

if ((CreateEventEx(myEventHandleHere) == nullptr)
{
    ...
}

【问题讨论】:

  • 如果函数在失败的情况下返回NULL,则应将其返回值与NULL进行比较。
  • @DavidSchwartz:很遗憾NULLnullptr 在这方面在各方面都是完全相同的。
  • 为什么不避免这个问题并写if (!CreateEventEx(myEventHandleHere))它甚至有点用英文阅读

标签: c++ null nullptr


【解决方案1】:

附录C.4中的draft C++ standard是非规范的C标准库说:

宏NULL,定义在 是 本国际中实现定义的 C++ 空指针常量 标准 (18.2)。

各自的规范部分同意例如18.2说:

宏 NULL 是实现定义的 C++ 空指针常量 在本国际标准 (4.10).194

这意味着如果您使用那些特定的标头 NULL 应该与 nullptr 兼容,然后我将只使用 nullptr

在涵盖兼容性的附录D 中似乎没有对.h 头文件做出类似的声明,因此尽管我们希望NULLnullptr 应该兼容空指针常量 em> 如果它们不是从标准的角度来看,我们会感到惊讶,它似乎至少被低估了。这让我们进退两难,从实际的角度来看,我们很确定它们是兼容的,但我们没有足够的标准信息来证明这一点。

所以我会使用您正在使用的特定头文件定义的NULL,或者我们可以使用!= 0,因为幸运的是C99和C++11都告诉我们0是一个空指针常量.

来自 C99 部分 6.3.2.3 指针

值为 0 的整数常量表达式,或这样的表达式 强制转换为 void * 类型,称为空指针常量。55) 如果为空 指针常量转换为指针类型,结果 指针,称为空指针,保证比较不等于 指向任何对象或函数的指针。

和:

任何指针类型都可以转换为整数类型。除了作为 之前指定,结果是实现定义的

和C++部分4.10指针转换告诉我们:

空指针常量是一个值为零的整数文字 (2.14.2) 或 std::nullptr_t 类型的纯右值。空指针常量可以是 转换为指针类型;结果是空指针值 该类型并且可与对象的所有其他值区分开来 指针或函数指针类型。[...]

【讨论】:

    【解决方案2】:

    它们是完全等价的,所以请使用nullptr,因为NULL 是一种原始的 C 主义,没有理由再活下去了。

    但是在 CreateEventEx 的情况下,您有一个有趣的好处,不是所有无效的 HANDLEs 都是 nullptr,其中一些是 INVALID_HANDLE_VALUE。所以在HANDLE 的情况下两者都不是真正的“安全”。您需要准确检查 CreateEventEx 在失败时返回的内容。

    【讨论】:

    • 我在道德上同意你的观点,但标准只说它等同于 <clocale>, <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>, or <cwchar> 或者至少我找不到适用于 .h 文件的声明。充其量它似乎模棱两可。
    • 定义上是等价的。包含函数原型的文件是无关紧要的。
    【解决方案3】:

    我会使用NULL,因为那是 C 使用的(另外,nullptr 在 C++11 中是新的,所以如果你不使用 C++11,那么你必须使用 NULL)。另一方面,您可以简单地不显式检查任何一个值,而是进行隐式比较,让编译器为您检查!= 0

    if (CreateEventEx(myEventHandleHere))
    {
        ...
    }
    

    您应该将值分配给一个变量,以便稍后释放它(如果这是 C API 所要求的):

    TypeName event = CreateEventEx(myEventHandleHere);
    if (event)
    {
        ...
        free event when done...
    }
    

    【讨论】:

      【解决方案4】:

      我不知道函数返回 NULL 的重要性。那是一个实现细节。有许多旧的 C++ 函数返回 NULL。许多新功能将返回nullptr。因此,如果您决定在 自己的代码中将空指针值从 NULL 切换到 nullptr,那么无论该函数是否恰好最初编写为 C . 编译成C++的时候就变成了C++函数了。

      但是。在这种情况下,返回类型是HANDLEHANDLE 实际上是 void* 的 typedef 这一事实是一个实现细节。 WinAPI 文档说当HANDLE 无效时,它与NULL 相当。在这种情况下,我建议您使用 WinAPI 文档,并使用NULL。如果 WinAPI 不使用 typedefs,只是将其所有函数记录为返回 void*,那么如果您在其余 C++ 代码中使用 nullptr,我将使用 nullptr

      【讨论】:

        猜你喜欢
        • 2013-06-29
        • 2010-12-30
        • 1970-01-01
        • 2017-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多