On Jul 28, 2009, at 9:53 PM, Roland Steiner wrote:
I definitely like the general idea, but I don't think a NeverNull
template is worth it in the general case, for the following reasons:
First, I don't hink you can catch even a meaningful subset of all
cases of NULL assignment at compile time. OTOH, writing a template
class that wraps a non-null pointer has its use mainly in order to
annotate header files, and to "auto-insert" the ASSERT. In cpp files
it's just a cosmetic difference to ASSERTs, and enforcing the use
throughout would probably change far too much code, and run into
other cumbersome details in addition to the ones I mention below.
Compile time checks are great, and any is better than none -- but even
runtime checks are an improvement, especially if you take the logical
step of adding a runtime check in _all_ builds. Effectively:
template <typename T> class NeverNull {
template <typename U> NeverNull(const U* ptr)
: m_ptr(ptr)
{
if (!ptr)
CRASH();
}
template <typename U> NeverNull(NeverNull<U> ptr)
: m_ptr(ptr.get())
{
}
T* get() { return m_ptr; }
...
}
NeverNull->NeverNull assignment circumvents the null check, and
assignment of a null pointer immediately crashes, rather than crashing
sometime later due to an "impossible" null. That way we can see
immediately when the crash is caused (on the assumption that assigning
null to a NeverNull _will_ crash eventually, so early crash is best).
OTOH in order to be consequent, one would also need to use
NeverNull<X> in return values, e.g.,
NeverNull<foo> bar() const;
Implementing such a function would have to be conscious of the fact
that a NeverNull<X> must always be initialized. i.e., you cannot write
NeverNull<foo> Baz::bar() const
{
NeverNull<foo> returnValue;
... compute returnValue ...
return returnValue;
}
Indeed, there should not be a default constructor to a NeverNull
Similar cases may also arise in other cases, when initialization is
non-trivial. So either one must us a tailored implementation, or use
plain pointers for the main computation. Both are somewhat defeating
the purpose, since they cause additional overhead.
Second, I believe that even if NeverNull<X> is a POD class, such
wrapping classes tend to defeat some compiler optimizations that
would be performed on raw pointers otherwise, so I'd be surprised to
not see any performance degradations. Whether or not they are
significant, I can't say.
The primary win for NeverNull is for members that will always be non-
null so any attempt to assign null is unsafe, and so that you don't
find yourself asking "can this be null?" all the time. I suspect
overall NeverNull would likely reduce the number of null checks in the
code base.
- Roland
--Oliver
_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev