I came across this code:
void f(const std::string &s);
And then a call:
f( *((std::string*)NULL) );
And I was wondering what others think of this construction, it is used to signal that function f() should use some default value (which it computes) instead of some user provided value.
I am not sure what to think of it, it looks weird but what do you think of this construction?
ToUpper(); The sample code above will throw a null reference exception during runtime because it tries to access a method on a type whose value is null. Null reference exceptions create poor user experiences, are hard to debug, and usually is a tell-tale sign of bad coding practices.
References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid. Note that for this reason, containers of references are not allowed.
Generally speaking, returning null from a method should be considered really bad. This forces the user of the method to do null checks and create conditional code paths.
The fundamental problem of null is that it is trying to represent the fact that it is not a value while being assigned as a value. This fundamental flaw then snowballs and manifests into problems that we see in everyday production code.
No. It is undefined behaviour and can lead to code to do anything (including reformatting you hard disk, core dumping or insulting your mother).
If you need to be able to pass NULL, then use pointers. Code that takes a reference can assume it refers to a valid object.
Addendum: The C++03 Standard (ISO/IEC 14882, 2nd edition 2003) says, in §8.3.2 "References", paragraph 4:
A reference shall be initialized to refer to a valid object or function. [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bit-field. ]
[Bold added for emphasis]
You will sometimes see constructions like this in fairly esoteric template library code, but only inside a sizeof()
where it is harmless.
Supposing you wanted to know the size of the return type of a function-like type F
if it was passed a reference to a type T
as an argument (both of those being template parameters). You could write:
sizeof(F(T()))
But what if T happens to have no public default constructor? So you do this instead:
sizeof(F(*((T *)0)))
The expression passed to sizeof
never executes - it just gets analyzed to the point where the compiler knows the size of the result.
I'm curious - does function 'f' actually check for this condition? Because if it doesn't, and it tries to use the string, then this is clearly going to crash when you try to use it.
And if 'f' does check the reference for NULL, then why isn't it just using a pointer? Is there some hard and fast rule that you won't use pointers and some knucklehead obeyed the letter of the law without thinking about what it meant?
I'd just like to know...
Is using NULL references OK?
No, unless you do not like your boss and your job ;)
This is something VERY bad. One of most important point of reference that it can't be NULL (unless you force it)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With