C ++: compare the return value of a C function with NULL or nullptr?
I am coding in C ++ and using a C function that returns NULL on failure. What would be the right thing to think about, compare its return value with NULL or nullptr?
if ((CreateEventEx(myEventHandleHere) == NULL)
{
...
}
or
if ((CreateEventEx(myEventHandleHere) == nullptr)
{
...
}
source to share
the draft C ++ standard in the C.4
C Appendix Standard Library, which is non-normative, says:
A NULL macro, defined in any of <clocale>, <cstddef>, <cstdio>, <<cstdlib>, <cstring>, <ctime>, or <cwchar>, is an implementation-defined C ++ constant constant in this International Standard (18.2).
the relevant normative sections are consistent, for example 18.2
says:
The NULL macro is an implementation-defined C ++ null pointer constant in this International Standard (4.10) .194
which would mean if you use those headers that NULL
should be compatible with nullptr
, then I would just use nullptr
.
The application D
that covers compatibility doesn't seem to make a similar statement for header files .h
, so while we expect NULL
and nullptr
should be null pointer constants compatible, and we'd be surprised if they weren't from a standard point of view, it is at least should be listed below. Which leaves us with a dilemma, from a practical point of view, we are confident that they are compatible, but we do not have enough information from the standard to prove this.
So I would use NULL
as defined by the specific header file you are using, or we can use != 0
, since luckily both C99 and C ++ 11 tell us what 0
is a null pointer constant.
In the C99 section 6.3.2.3
Pointers:
An integer constant expression with a value of 0 or such an expression cast to type void * is called a null pointer constant. 55) If a null pointer constant is cast to a pointer type, the result is a pointer called a null pointer guaranteed to compare unevenly with a pointer to any object or function ...
and
Any pointer type can be converted to an integer type. Also, previously stated, the result is implementation-defined
and the C ++ section 4.10
Pointer Conversions tell us:
A null pointer constant is an integer literal (2.14.2) with a value of 0 or a prvalue of type std :: nullptr_t. A null pointer constant can be converted to a pointer type; the result is a null pointer value of that type and is different from any other pointer object value or a function pointer type. [...]
source to share
They are exactly and completely equivalent, so use nullptr
because it NULL
is a primitive C-ism that has no reason to live any longer.
But in the case of CreateEventEx, you have a hilarious bonus of not all the invalid ones HANDLE
being nullptr
, but some of them INVALID_HANDLE_VALUE
. Thus, none of them are "safe" in the case HANDLE
. You need to check exactly what CreateEventEx returns on error.
source to share
I would use NULL
since this is what C uses (also, nullptr
is new in C ++ 11, so if you are not using C ++ 11 you need to use NULL
). On the other hand, you may simply not be checking one value explicitly, implying a comparison instead, let the compiler check != 0
for you:
if (CreateEventEx(myEventHandleHere))
{
...
}
You must assign a value to a variable so that you can release it later (if required by the C API):
TypeName event = CreateEventEx(myEventHandleHere);
if (event)
{
...
free event when done...
}
source to share
I'm not sure why it matters if the function returns NULL. This is an implementation detail. There are many old C ++ functions that return NULL. And many new features will return nullptr
. So, if you decide to switch from NULL
to nullptr
to null pointer values in your own code, then you have to be consistent in that, whether or not the function originally written as C. When it is compiled as C ++, it becomes C + + -function.
However. In this case, the return type is HANDLE
. The fact that HANDLE
a is actually a typedef for a void*
is an implementation detail. The WinAPI documentation says that when a is HANDLE
invalid, it matches NULL
. In this case, I suggest you go to the WinAPI documentation and use NULL
. If WinAPI didn't use typedefs and just documented all of its functions as returning void*
, then I would use nullptr
if you use nullptr
in the rest of your C ++ code.
source to share