How to Protect from 0 Passed to std::string Parameters in C++

c

I have just realized something disturbing. Every time I have written a method that accepts a std::string as a paramater, I have opened up myself to undefined behaviour.

For example, this…

void myMethod(const std::string& s) { 
    /* Do something with s. */
}

…can be called like this…

char* s = 0;
myMethod(s);

…and there's nothing I can do to prevent it (that I am aware of).

So my question is: How does someone defend themself from this?

The only approach that comes to mind is to always write two versions of any method that accepts an std::string as a parameter, like this:

void myMethod(const std::string& s) {
    /* Do something. */
}

void myMethod(char* s) {
    if (s == 0) {
        throw std::exception("Null passed.");
    } else {
        myMethod(string(s));
    }
}

Is this a common and/or acceptable solution?

EDIT: Some have pointed out that I should accept const std::string& s instead of std::string s as a parameter. I agree. I modified the post. I don't think that changes the answer though.

Best Answer

I don't think you should protect yourself. It's undefined behavior on the caller's side. It's not you, it's the caller who calls std::string::string(nullptr), which is what is not allowed. The compiler lets it be compiled, but it lets other undefined behaviors be compiled as well.

The same way would be getting "null reference":

int* p = nullptr;
f(*p);
void f(int& x) { x = 0; /* bang! */ }

The one who dereferences the null pointer is making UB and is responsible for it.

Moreover, you cannot protect yourself after undefined behavior has happened, because the optimizer is in its full right to assume that the undefined behavior had never happened, so the checks if c_str() is null can be optimized out.