问题
I'm coding in C++, and using a C function that returns NULL in case of a failure. What would be the correct think to do, compare its return value to NULL or nullptr?
if ((CreateEventEx(myEventHandleHere) == NULL)
{
...
}
or
if ((CreateEventEx(myEventHandleHere) == nullptr)
{
...
}
回答1:
The draft C++ standard in appendix C.4
C Standard library which is non-normative says:
The macro NULL, defined in any of <clocale>, <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>, or <cwchar>, is an implementation-defined C++ null pointer constant in this International Standard (18.2).
the respective normative sections agree for example 18.2
says:
The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10).194
which would mean if you are using the those particular headers NULL
should be compatible with nullptr
and then I would just use nullptr
.
In appendix D
which covers compatibility does not seem to make a similar statement for .h
header files, so although we would expect that NULL
and nullptr
should be compatible null pointer constants and we would be surprised if they were not from the standard point of view it seems at minimum to be underspecified. Which leaves us with a dilemma, from a practical perspective we are pretty sure they are compatible but we don't have enough information from the standard to prove it.
So I would use NULL
as defined by the specific header file you are using or we can use != 0
since fortunately both C99 and C++11 tell us that 0
is a null pointer constant.
From C99 section 6.3.2.3
Pointers:
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
and:
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined
and C++ section 4.10
Pointer conversions tells us:
A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type.[...]
回答2:
They are exactly and totally equivalent, so use nullptr
because NULL
is a primitive C-ism that has no reason to live anymore.
But in the case of CreateEventEx you have the hilarious bonus of not all invalid HANDLE
s being nullptr
, some of them are INVALID_HANDLE_VALUE
instead. So neither is really "safe" in the case of HANDLE
. You need to check exactly what CreateEventEx returns on failure.
回答3:
I would use NULL
since that is what C uses (also, nullptr
is new in C++11, so if you are not using C++11 then you have to use NULL
). On the other hand, you could simply not check for either value explicitly, do an implicit comparison instead, let the compiler check for != 0
for you:
if (CreateEventEx(myEventHandleHere))
{
...
}
You should assign the value to a variable so you can free it later (if that is what the C API requires):
TypeName event = CreateEventEx(myEventHandleHere);
if (event)
{
...
free event when done...
}
回答4:
I'm not sure why it matters if the function returns NULL. That is an implementation detail. There are many old C++ functions which return NULL. And many new functions will return nullptr
. So, if you decide to switch from NULL
to nullptr
for null pointer values in your own code, then you should be consistent about that, regardless of whether the function happens to originally written as C. When it is compiled as C++, it becomes a C++ function.
However. In this case, the return type is a HANDLE
. The fact that HANDLE
is actually a typedef for a void*
is an implementation detail. The WinAPI documentation says that when a HANDLE
is invalid, it is comparable to NULL
. In this case, I would suggest you go with the WinAPI documentation, and use NULL
. If the WinAPI didn't use typedefs, and just documented all its functions as returning void*
, then I would use nullptr
, if you use nullptr
in the rest of your C++ code.
来源:https://stackoverflow.com/questions/25650592/c-compare-return-value-of-c-function-to-null-or-nullptr