I am working on a small c++ program and learning exceptions. Is the following code "bad", and if so, what can I do to improve it?
try { // code if (some error) { throw "Description of error."; } } catch (char* errorMessage) { cerr << errorMessage << endl << "Fatal error"; }
Is there anything wrong with throwing a char
array as an exception?
EDIT: Would this be a better way to go?
const char errorMessage[] = "Description of error"; try { // code if (some error) { throw errorMessage; } } catch (char* errorMessage) { cerr << errorMessage << endl << "Fatal error"; }
Can shrinking a std::string throw an exception? The question is whether this function can throw an exception. Can the call to resize throw an exception when used to make a string smaller? And the answer appears to be yes, at least in C++17.
C doesn't support exceptions. You can try compiling your C code as C++ with Visual Studio or G++ and see if it'll compile as-is. Most C applications will compile as C++ without major changes, and you can then use the try... catch syntax.
This is thrown when a too big std::string is created. This can be thrown by the 'at' method, for example a std::vector and std::bitset<>::operator[](). An exception that theoretically cannot be detected by reading the code.
Your function will terminate immediately, and it won't return anything. If there are no catch statements catching the exception "up the call chain", your application will terminate.
It is much better to throw a standard exception object. In general, the best practice is to throw something derived from std::exception
so that if in some situation it does cause your program to terminate, the implementation has a better chance of printing a useful diagnostic.
Because it isn't hard to do this, I would never recommend throwing a raw string literal.
#include <stdexcept> void someFunction() { try { // code if (some error) { throw std::runtime_error( "Description of error." ); } } catch (const std::exception& ex) { std::cerr << ex.what() << "\nFatal error" << std::endl; } }
Throwing a string literal is generally a bad idea because, as the code evolves, programmers may need to enrich the error message with some more information, e.g. the value of a variable, or the line number from which the exception is thrown.
Given unknown client code that's catching const char*
, the programmer's encouraged to use a more dynamic mechanism to concatenate desired information:
std::string
and +
std::ostringstream
strcat
and/or sprintf()
The most obvious ways of using these don't work or don't work well:
// temporaries... throw (std::string("couldn't parse input: ") + input).c_str(); throw (std::ostringstream() << "error line " << __LINE__).str().c_str(); char buf[1024]; sprintf(buf, "error line %ld%", __LINE); throw buf; // not thread-safe static char buf...
Even if the programmer knows not to do any of these, they'll still have a right time finding all the client code that needs to start accepting a richer value type, especially if other throw
/catch
usage of const char*
persists.
So, using a class that embeds a flexible std::string
description by value is very important for writing maintainable code.
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