C++:比较C函数的返回值与NULL或nullptr?

4

我正在使用C++编程,并使用返回NULL的C函数来处理失败情况。应该怎么做,将其返回值与NULL或nullptr进行比较?

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

或者

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

使用nullptr - 参考http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr - user2249683
如果函数在失败的情况下返回 NULL,你应该将其返回值与 NULL 进行比较。 - David Schwartz
@DavidSchwartz:很遗憾,在这方面,“NULL”和“nullptr”在每个方面都是完全相同的。 - Puppy
2
为什么不避免这个问题并写成 if (!CreateEventEx(myEventHandleHere)),它甚至在英语中读起来也很好。 - Colander
4个回答

5
在附录C.4《C标准库》中,非规范性地指出:草案C++标准中的宏NULL,在任何、、、、、或头文件中定义,是本国际标准(18.2)中一个实现定义的C++空指针常量。相应的规范部分也同意,例如18.2表示:宏NULL是本国际标准(4.10)中一个实现定义的C++空指针常量。这就意味着如果您使用这些特定的头文件,则NULL应与nullptr兼容,那么我会使用nullptr。
在涵盖兼容性的附录D中,似乎没有为.h头文件做出类似的声明,因此尽管我们期望NULL和nullptr应该兼容,而且从标准的角度来看,如果它们不兼容,我们会感到惊讶,但最少是未明确说明的。这使我们陷入了困境,从实际角度来看,我们相当确定它们是兼容的,但我们没有足够的标准信息来证明它。所以我将使用特定头文件定义的NULL,或者我们可以使用!=0,因为幸运的是,C99和C++11告诉我们0是一个空指针常量。
从C99第6.3.2.3节“指针”中:
如果一个值为0的整数常量表达式,或这样一个表达式转换为void*类型,则称为空指针常量。如果将空指针常量转换为指针类型,则得到的指针称为空指针,保证与任何对象或函数的指针不相等。
并且:
除非以前有规定,否则任何指针类型都可以转换为整数类型。结果是实现定义的。
C++第4.10节“指针转换”告诉我们:

空指针常量是一个整数字面值(2.14.2),其值为零,或者是std :: nullptr_t类型的prvalue。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且与对象指针或函数指针类型的每个其他值不可区分。[...]

说明:本文介绍了空指针常量的定义和用法,空指针可用于表示一个无效的指向对象的指针。在C++中,空指针可以用0或nullptr来表示。

2
它们完全等效,因此请使用nullptr,因为NULL是一种原始的C语言习惯用法,没有理由继续存在。
但是,在CreateEventEx的情况下,你有一个搞笑的奖励:并非所有无效的HANDLE都是nullptr,有些实际上是INVALID_HANDLE_VALUE。因此,在HANDLE的情况下,两者都不是真正的“安全”的。你需要检查CreateEventEx在失败时确切返回什么。

1
道德上我同意你的观点,但标准只是说对于<clocale>、<cstddef>、<cstdio>、<cstdlib>、<cstring>、<ctime>或<cwchar>等文件等价,至少我没有找到适用于.h文件的声明。最好情况下似乎存在歧义。 - Shafik Yaghmour
1
根据定义,它是等效的。包含函数原型的文件是无关紧要的。 - Puppy

0

我会使用 NULL 因为这是 C 语言所使用的(而且,nullptr 是 C++11 的新特性,如果你没有使用 C++11,那么你必须使用 NULL)。另一方面,你可以不显式地检查任何一个值,而是进行隐式比较,让编译器为你检查 != 0

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

你应该将值分配给变量,这样以后就可以释放它(如果 C API 需要的话):
TypeName event = CreateEventEx(myEventHandleHere);
if (event)
{
    ...
    free event when done...
}

-1

我不确定函数返回NULL是否重要。这是一个实现细节。有许多旧的C++函数返回NULL。而许多新函数将返回nullptr。因此,如果您决定在自己的代码中从NULL切换到nullptr以获取空指针值,则无论该函数最初是作为C编写的,都应始终如一。当它被编译为C++时,它就成为了一个C++函数。

然而,在这种情况下,返回类型是HANDLE。事实上,HANDLE实际上是void*的typedef,这是一个实现细节。WinAPI文档说,当HANDLE无效时,它可与NULL进行比较。在这种情况下,我建议您遵循WinAPI文档,并使用NULL。如果WinAPI没有使用typedefs,并且只记录所有函数返回void*,则如果您在其余的C++代码中使用nullptr,我会使用nullptr


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接