C++ Exception:Throwing Std::String

c++ exception : throwing std::string

Yes. std::exception is the base exception class in the C++ standard library. You may want to avoid using strings as exception classes because they themselves can throw an exception during use. If that happens, then where will you be?

boost has an excellent document on good style for exceptions and error handling. It's worth a read.

C++ Exception - Throw a String

You are currently throwing a const char* and not a std::string, instead you should be throwing string("error")

edit: the error is resolved with

throw string("exception ! error");

String throwing exception

I do not know what you are trying to experiment, but despite being allowed by the language, throwing objects that are not instances of (subclasses of) std::exception should be avoided.

That being said you have a bunch of inconsistencies in your code.

First cin >> x.second; will stop at the first blank character. So in your example you have only "1," in x.second, so you test fails and you code does not throw anything.

You should ignore the newline left by cin >> x.first and use getline to read a full line include spaces:

P x;
cin >> x.first;
cin.ignore();
std::getline(cin, x.second);

The first try block invokes UB, because you are declaring a new x in that block that will hide the one you have just read. It should be:

try
{
//P x; // do not hide x from the enclosing function!
T(x);
}

Finaly, and even it is not an error you should always catch non trivial object by const reference to avoid a copy. Remember that exceptions are expected to be raised in abnormal conditions, and when memory becomes scarce you should avoid copy. But you must catch the exact same object that was thrown. So the second catch should be:

catch (std::string exception)
{
std::cout << "\n" << exception;
}

or better (avoid a copy):

catch (const std::string& exception)
{
std::cout << "\n" << exception;
}

How to throw std::exceptions with variable messages?

Here is my solution:

#include <stdexcept>
#include <sstream>

class Formatter
{
public:
Formatter() {}
~Formatter() {}

template <typename Type>
Formatter & operator << (const Type & value)
{
stream_ << value;
return *this;
}

std::string str() const { return stream_.str(); }
operator std::string () const { return stream_.str(); }

enum ConvertToString
{
to_str
};
std::string operator >> (ConvertToString) { return stream_.str(); }

private:
std::stringstream stream_;

Formatter(const Formatter &);
Formatter & operator = (Formatter &);
};

Example:

throw std::runtime_error(Formatter() << foo << 13 << ", bar" << myData);   // implicitly cast to std::string
throw std::runtime_error(Formatter() << foo << 13 << ", bar" << myData >> Formatter::to_str); // explicitly cast to std::string

Throw string exception from inherited exception class

You are experiencing object slicing.

This happens when a derived instance is received by value as its base class -- In your case, catching std::exception by value. Your derived class' member is "sliced off" in the process of conversion to the base class.

Receiving by pointer or by (const) reference is always preferable when you expect to use a parameter polymorphically. For catching a std::exception you should always catch by const reference (I can't really think of a scenario where you wouldn't).

Can std::string::compare(const char*) throw an exception?

Except for destructors, swap functions, move constructors and move assignment operators, the standard marks a function noexcept only if it has a wide contract, i.e., it has no preconditions. This overload requires the argument to be a null-terminated string, so the standard does not mark it as noexcept.

The rational is specified in N3248:

Functions marked noexcept are difficult to test


When a function is marked with noexcept it becomes impossible to flag test failures,
notably in test drivers, by throwing an exception. A common example would be code
that validates preconditions on entry to a function:

T& std::vector<T>::front() noexcept {
assert(!this->empty());
return *this->data();
}

When validating such defensive checks from a test driver, a reasonable approach is to
register an assert-handler that throws a well-defined precondition-violated exception,
which the test driver catches to ensure that the appropriate asserts are indeed in
place.

...

Now we might argue that calling the function out-of-contract, when the vector is
empty, is undefined behavior so we should not expect any guarantees. The problem is that undefined behavior is being specified by the library; to the compiler, this code is
perfectly well defined and, if assert throws an exception, the program must terminate
in a well-specified manner, thwarting the test driver.

Note that the issue here is not that we are using assertions to find bugs in our own
library implementations, but rather in user code that incorrectly calls into our library.
If we remove the ability to test these defensive assertions, we may get them wrong,
and thus put our users at risk for committing far more serious errors than propagating
an unexpected exception.


By the way, due to [res.on.exception.handling]/5:

An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.

... libstdc++ and libc++ are free to mark this overload noexcept.

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

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;
}
}


Related Topics



Leave a reply



Submit