简体   繁体   中英

C++ Exception testing

I want to test what exception was returned. In all examples on exception handling I see they are just printing some message, no real test on the type of exception. So I tried this:

string Out_of_range{ "stol argument out of range" };
long Long;
try{
    Long = stol( "12345678901234567890" );

} catch( exception& Ex ){
    string What = Ex.what();
    if( What == Out_of_range )
        cout << "OK 1\n";;
    if( Ex.what() == What )
        cout << "OK 2\n";;
    if( Ex.what() == Out_of_range )
        cout << "OK 3\n";;
    if( Ex.what() == "stol argument out of range" )
        cout << "OK 4\n";;
}

and the result is

OK 1
OK 2
OK 3

Question 1: why is the fourth if statement false?

Question 2: is there another way to test an exception than using the what member?

"Question 1: why is the fourth if statement false?"

The signature of std::exception::what() is

virtual const char* what() const;

It's pretty unlikely that the string literal and the result of what() are pointing to the same memory address which are compared in your case.

"Question 2: is there another way to test an exception than using the what member?"

Yes. Use multiple catch() {} blocks, one for each particular exception type. Also you should catch() exceptions by const reference:

try{
    Long = stol( "12345678901234567890" );

} catch(const std::invalid_argument& Ex) {
    // Handle invalid_argument exception
} catch(const std::out_of_range& Ex) {
    // Handle out_of_range exception
} catch( ... )
    // Handle unexpected exception
} 

Question 1: why is the fourth if statement false?

In that line you are comparing two char const* , not two strings.

Question 2: is there another way to test an exception than using the what member?

std::stol can throw the following exceptions ( http://en.cppreference.com/w/cpp/string/basic_string/stol ):

  • std::invalid_argument if no conversion could be performed
  • std::out_of_range if the converted value would fall out of the range of the result type or if the underlying function ( std::strtol or std::strtoll ) sets errno to ERANGE .

You can use explicit catch blocks for those two types of exceptions.

try
{
   Long = stol( "12345678901234567890" );
}
catch( std::invalid_argument const& Ex )
{
   // Deal with the exception
}
catch( std::out_of_range const& Ex )
{
   // Deal with the exception
}
catch( exception const& Ex )
{
   // Deal with the exception
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM