4

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

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

或者

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

4 回答 4

5

附录C 标准库中非规范的C++ 标准草案说:C.4

在 <clocale>、<cstddef>、<cstdio>、<cstdlib>、<cstring>、<ctime> 或 <cwchar> 中定义的宏 NULL 是本国际标准中实现定义的 C++ 空指针常量(18.2)。

相应的规范性部分同意例如18.2说:

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

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

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

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

从 C99 部分6.3.2.3 指针

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

和:

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

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

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

于 2014-09-04T01:49:17.673 回答
2

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

但是在 CreateEventEx 的情况下,你有一个有趣的好处,不是所有的 invalid HANDLEs being nullptr,它们中的一些是INVALID_HANDLE_VALUE相反的。因此,在HANDLE. 您需要准确检查 CreateEventEx 在失败时返回的内容。

于 2014-09-03T18:45:11.870 回答
0

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

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

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

TypeName event = CreateEventEx(myEventHandleHere);
if (event)
{
    ...
    free event when done...
}
于 2014-09-03T17:51:44.267 回答
-1

我不确定如果函数返回 NULL 为什么会很重要。那是一个实现细节。有许多旧的 C++ 函数返回 NULL。许多新功能将返回nullptr。因此,如果您决定在自己的NULL代码中从空指针值切换到nullptr空指针值,那么您应该对此保持一致,无论该函数是否最初是用 C 编写的。当它被编译为 C++ 时,它变成了一个 C++ 函数.

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

于 2014-09-03T18:22:23.140 回答