Home > Software design >  How to deal with possible errors that arise from dereferencing a nullptr?
How to deal with possible errors that arise from dereferencing a nullptr?

Time:06-29

I have a question regarding some guidelines to write better code. Suppose that I have a class like this:

class A {
private:
    T *m_data;
public: 
    A(T *data) : m_data(data) {}
    
    void doSomething() {
        //accessing m_data
    } 
};

Since it's possible to call A constructor passing a nullptr, what is the correct way to handle this problem in optic to be helpful to someone who want to re-use my code ? A comment with a precondition is enough ?

//precondition : m_data != nullptr
void doSomething() {
        //accessing m_data
    } 

Or is it better to check if m_data==nullptr and throw an exception with an error message giving the possibility to handle it or to let the program abort?

CodePudding user response:

The short answer is always: there is no single correct way, or rule that always applies.

For example, suppose your class is the start of a custom iterator definition. Dereferencing default-constructed or end() iterators is usually undefined behaviour, even if they don't represent null values. The non-default constructor could be similar to yours, but since users aren't supposed to call it directly and the behaviour is documented, that's not really a problem. But still, the iterator simply assumes that it's in a valid state and will let you violate these rules. It provides a default constructor (and would therefore avoid having reference members) just to be "regular", which is a convenient and intuitive property.

So in that case, it doesn't really matter whether the constructor accepts a pointer or a reference, as long as the class does not do anything surprising with the referenced object, such as destroying it. However, your case may be different and so your design may end up being different. In general your code should be unsurprising and self-documenting as much as possible. What is surprising is of course subjective, but I personally find a class that is not (semi)regular more surprising than one whose default-constructed state is invalid in some sense. You could look at resources like the ISO C guidelines, especially interfaces and functions for many well-documented examples, both good and bad ones!

  • Related