Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Violation when sending a 0 int literal to a const string parameter

Tags:

c++

On VS2015 and VS2017, this compiles with no warning, and generates an access violation that cannot be caught and crashes the application. Obviously the int 0 is silently converted to a null pointer which is then assumed to point to a string hence crashing.

#include <string>
#include <iostream>
void crash(const std::string& s) {}
int main()
{
    try
    {
        crash(0);
    }
    catch (const std::exception& ex)
    {
        // never gets here!
        std::cout << "got" << ex.what() << std::endl;
    }
}

How can I trap and recover from such an exception? If I drop the const from the function parameter it does not compile - so that's maybe one way to guard from misuse by users, but I would lose the protection provided by the const, or would I? What's the best practice to write prototypes that avoid this problem?

like image 426
Yaniv Avatar asked Jan 11 '18 15:01

Yaniv


1 Answers

For this specific case, you can get a compile time error by using C++11 std::nullptr_t, just add the following deleted overload:

void crash(std::nullptr_t) = delete;

Of course, this won't protect you against passing null (or non-null-terminated ) char* pointers ... you are violating an std::string constructor precondition, resulting in undefined behavior; this is by definition unrecoverable.

Alternatively, if you really need to catch these errors at runtime in a possibly recoverable way, you could write a const char* overload that throws if given a null pointer or invokes the std::string const& version otherwise.

If your real function takes more than a few string arguments, and overloading all possible combinations seems not feasible, you could resort writing a function template, performing all the checks over the deduced types ex-post.

like image 50
Massimiliano Janes Avatar answered Sep 24 '22 18:09

Massimiliano Janes