Search code examples
c++stringpointersstring-comparison

Why is it not possible to compare the output of .what() method of thrown exception with a string?


The code fails to print True because the comparison fails for some reason. I don't know what it's, but it works if I change e.what() == "Something Bad happened here" to e.what() == std::string("Something Bad happened here")

#include <iostream>
#include <string>
#include <stdexcept>

int main() {
    try
    {

        throw std::runtime_error("Something Bad happened here");

    }
    catch(std::exception const& e)
    {
        if(e.what() == "Something Bad happened here") {
            std::cout << "True" << "\n";
        }
    } 
}

Solution

  • Because std::exception::what() returns a const char*, and a "string literal" is a const char[N]. Operator == on them does a comparison of two pointers. You must use strcmp() on them

    if (strcmp(e.what(), "Something Bad happened here") == 0) // ...
    

    std::string OTOH has an operator== to compare with a const char*


    If you have C++14 then you can get a std::string without an explicit constructor with the s suffix

    using namespace std::string_literals;
    if (e.what() == "Something Bad happened here"s) // ...
    

    But of course a std::string is still needed to be constructed before comparing, which may be a little bit slower than strcmp when SSO doesn't kick in


    In C++17 there's std::string_view which needs pretty much zero cost to construct from a string literal, so you can use this

    using namespace std::literals::string_view_literals;
    if (e.what() == "Something Bad happened here"sv) // ...