问题
I'm currently grinding through some third-party C++ code that looks rather odd to me (I started out with C++11). One of the many things that left me puzzled, are the many instances of static_cast
from NULL
to some pointer type:
SomeClass* someClassPtr = static_cast<SomeClass*>(NULL);
I know you can cast pointers e.g. from a base class pointer into a derived class pointer, but there is absolutely no inheritance going on here. As far as I can see, this should be enough:
SomeClass* someClassPtr = NULL;
But the only cases in this code, where NULL
does not get casted to a specific pointer type, are pointers in vectors and other containers:
SomeOtherClass.vecOfSomeClassPtr[i] = NULL;
So my questions are:
- Is this simply old-style (or even C-style) code from before there was
nullptr
? - Is/was casting
NULL
necessary for other things than down-/upcasting when working with inheritance? - Or am I missing something completely?
And in case I haven't gotten it wrong so far:
I first replaced all instances of static_cast<type*>(NULL)
with NULL
and later nullptr
, to see if that would break anything: Nope.
The compiler doesn't protest and the program still seems to work as expected.
But I know pointers can be tricky little bastards, so:
- What pitfalls about the use of
nullptr
did I probably miss?
PS: Yes, I did use the search and yes, I did find similar questions on C code. But this is C++ code and I wanted to know for sure, instead of just assuming something.
回答1:
What's the use of casting NULL to SomeType* in C++?
SomeClass* someClassPtr = static_cast<SomeClass*>(NULL);
The cast has no effect in this context.
However more generally, it does make sense in some other context where overloading is involved:
void stupidly_overloaded_function(int);
void stupidly_overloaded_function(SomeClass*);
void stupidly_overloaded_function(SomeOtherClass*);
stupidly_overloaded_function(NULL);
which function gets called? It actually depends on the definition of NULL
. Either it calls the int
overload, or compilation fails due to ambiguity.
A cast can disambiguate the call:
stupidly_overloaded_function(static_cast<SomeClass*>(NULL));
I think this is a significant reason for introducing nullptr
. Although even nullptr
cannot deal with multiple different pointer overloads, it does disambiguate between integers:
void not_quite_as_silly_overload(int);
void not_quite_as_silly_overload(SomeClass*);
not_quite_as_silly_overload(NULL); // might call either overload
not_quite_as_silly_overload(nullptr); // unambiguously calls the pointer overload
Another case in C is macros involved with sizes of objects, such as the container_of
macro from the Linux kernel:
define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
Here, just 0 is used instead of NULL
. I think that this could be implemented in C++ without the cast, but only using declval
which was introduced in C++11.
Is this simply old-style (or even C-style) code from before there was nullptr?
No, there was no universal style for such redundant casts. Your example has no overloading, so the above case does not apply to it.
Is/was casting NULL necessary for other things than down-/upcasting when working with inheritance?
No, it was (and still is in the case of different pointer overloads) necessary for overload resolution.
来源:https://stackoverflow.com/questions/44117134/whats-the-use-of-casting-null-to-sometype-in-c