[webkit-dev] NeverNull<T>

Oliver Hunt oliver at apple.com
Tue Jul 28 22:07:08 PDT 2009

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)
     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


More information about the webkit-dev mailing list