If I come across old code that does if (!this) return;
in an app, how severe a risk is this? Is it a dangerous ticking time bomb that requires an immediate app-wide
I would leave it alone. This might have been a deliberate choice as an old-fashioned version of the SafeNavigationOperator. As you say, in new code, I wouldn't recommend it, but for existing code, I'd leave it alone. If you do end up modifying it, I'd make sure that all calls to it are well-covered by tests.
Edit to add: you could choose to remove it only in debug versions of your code via:
CThingy *CLookupThingy::Lookup( name )
{
#if !defined(DEBUG)
if (!this)
{
return NULL;
}
#endif
// else do the lookup code...
}
Thus, it wouldn't break anything on production code, while giving you a chance to test it in debug mode.
If it's something that's bothering you today, it'll bother you a year from now. As you pointed out, changing it will almost certainly introduce some bugs -- but you can begin by retaining the return NULL
functionality, add a bit of logging, let it run in the wild for a few weeks, and find how many times it even gets hit?
this is something that's called 'a smart and ugly hack'. note: smart != wise.
finding all the call sites without any refactoring tools should be easy enough; break GetLookup() somehow so it doesn't compile (e.g. change signature) so you can identify misusage statically. then add a function called DoLookup() which does what all this hacks are doing right now.
Future versions of the compiler are likely to more aggressively optimize in cases of formally undefined behavior. I wouldn't worry about existing deployments (where you know the behavior the compiler actually implemented), but it should be fixed in the source code in case you ever use a different compiler or different version.
Like all undefined behavior
if (!this)
{
return NULL;
}
this is a bomb waiting to go off. If it works with your current compilers, you are kind-of lucky, kind-of unlucky!
The next release of the same compilers might be more aggressive and see this as dead code. As this
can never be null, the code can "safely" be removed.
I think it is better if you removed it!
It may not crash in most compilers since non-virtual functions are typically either inlined or translated into non-member functions taking "this" as a parameter. However, the standard specifically says that calling a non-static member function outside the lifetime of the object is undefined, and the lifetime of an object is defined as beginning when memory for the object has been allocated and the constructor has completed, if it has non-trivial initialization.
The standard only makes an exception to this rule for calls made by the object itself during construction or destruction, but even then one must be careful because the behavior of virtual calls can differ from the behavior during the object's lifetime.
TL:DR: I'd kill it with fire, even if it will take a long time to clean up all the call sites.