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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With