Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Exceptions - Is throwing c-string as an exception bad?

Tags:

c++

exception

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"; } 
like image 820
Tim Avatar asked Jun 06 '11 06:06

Tim


People also ask

Can STD string throw exceptions?

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.

Can you throw exceptions in C?

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.

Can we throw a string in C++?

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.

What will happen if thrown exception is not handled in C Plus Plus?

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.


2 Answers

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;     } } 
like image 177
CB Bailey Avatar answered Sep 21 '22 21:09

CB Bailey


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:

  • a std::string and +
  • a std::ostringstream
  • a char buffer and perhaps 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.

like image 34
Tony Delroy Avatar answered Sep 20 '22 21:09

Tony Delroy