The following is a custom exception class from another person's c++ tutorial:
class MyException : public std::exception {
public:
MyException(const std::string message) : m_message(message) { }
~MyException() throw() { }
const std::string what() const throw() { return m_message.c_str(); }
private:
std::string m_message;
}
I get most of what going on here,, except for the "throw()" right next to the destructor..
Does it mean throw() is called whenever the exception class is destructed..??
This is an exception specification.
It means that the destructor is not supposed to throw any exception. If it attempts to throw one anyway, the program will invoke std::terminate (which will almost certainly crash the program). Note that not all compilers implement this behavior correctly (most notably, in VC++ throwing from a destructor declared throw() leads to unspecified behavior).
Note that exception specifications have been deprecated with C++11 in favor of noexcept and should no longer be used (for good reasons). Destructors are implicitly noexcept in C++11.
It's a declaration of what the function is allowed to throw. In this case, nothing.
See http://en.cppreference.com/w/cpp/language/except_spec
If you don't list an exception type inside the throw() and you later try to throw one from that function, you'll get an std::unexpected thrown instead.
If the throw() is left out as it usually is, then any exception may be thrown.
Related
I came from c++98, and i am trying to make my way in to c++11 and so on. i came across the public member function , std::exception::what, <=> virtual const char* what() const noexcept;
from this example givin in c++ reference : what_example, i can understand the usage but i have a few questions:
// exception::what
#include <iostream> // std::cout
#include <exception> // std::exception
struct ooops : std::exception {
const char* what() const noexcept {return "Ooops!\n";}
};
int main () {
try {
throw ooops();
} catch (std::exception& ex) {
std::cout << ex.what();
}
return 0;
}
in c++98 the what() was : virtual const char* what() const throw();, and in c++11, it becomes virtual const char* what() const noexcept;. what is the noexcept at the end? did it bring something new?
why should i use what() it at all? i can emplement my own tostring method in my class exception and call it instead!
in the return value of what(), see below, guaranteed to be valid at least until...or until a non-const member function of the exception object is called. what is the meaning of or until a non-const member function of the exception object is called, could some one explain with example and why is that ?
what() return value
A pointer to a c-string with content related to the exception. This is
guaranteed to be valid at least until the exception object from which
it is obtained is destroyed or until a non-const member function of
the exception object is called.
thanks.
what is the noexcept at the end?
It is a new specifier introduced in C++11. In very short, it means that the function will not throw an exception. noexcept has same meaning as throw().
did it bring something new?
noexcept is an improvement over the old throw specifier, which has since been deprecated (C++11) and then removed (C++20) from the language. It accepts a boolean expression that determines whether the function is noexcept or potentially throwing. This is useful in generic template programming because some instances of a template may be potentially throwing while others might not be.
why should i use what() it at all? i can emplement my own tostring method in my class exception and call it instead!
Because you may be using functions that are not written by you, and therefore will not throw your exception class. For example, some standard functions will in some cases throw an exception, and all standard exceptions derive from std::exception. In such case, the only way to access the error message is through the what member function.
Same applies when other people call your function. They might not want to / or need to know about your special exception class, but they can still catch it and print the message if you inherit std::exception.
what is the meaning of or until a non-const member function of the exception object is called
The meaning is literal. If you call what on an exception object derived from std::exception, and store the returned pointer, and then call a non-const member function of that exception object then the stored pointer will be invalid.
Any attempt to indirect through an invalid pointer such as attempting to print the exception message will result in undefined behaviour.
For your first question check out StoryTeller's comment. As for the second point:
why should i use what() it at all? i can emplement my
own tostring method in my class exception and call it instead!
The first rule of programming is do not reinvent the wheel, if there is a toString function or another function in the STL library that meets your needs, use it. Do not invent your own and try to debug it.
As an addition to the third question:
Sometimes, one happens to be surprised how important it can be that the wheel is not reinvented; and sharing the same basic class can be a big deal.
Thus, there comes a std::cerr message showing the contents of what, when the program crashes because of a thrown exception.
Lets say I have a constructor like so
Something(SomethingElse) noexcept : member{SomethingElse, something_that_might_throw()} {
...
}
Is a noexcept okay in this case if the construction of member can throw? In the above example the member variable member is of a type I do not know.
On a side note: Are there other edge cases one needs to worry about when using noexcept?
#UPDATE:(Based on your edit): The original answer applies to everything within the block-scope of the function (constructors inclusive, including constructor-initialization-list). Why don't you try the code and see. :-)
#Original Answer
Something(SomethingElse) : member{SomethingElse} noexcept {
...
}
Your code would not compile that way. noexcept comes before the colon :
Something(SomethingElse) noexcept : member{SomethingElse} {
...
}
To your question:
Is a noexcept okay in this case if the member class constructor can
throw?
No, it's not okay. The noexcept specifier is a promise that an exception will not leave that function or constructor. Should it leave, the runtime will terminate your program.
If a search for a matching exception handler leaves a function marked
noexcept or noexcept(true), std::terminate is called immediately.
This applies to the constructor.
Despite the try..catch block, the code below gets terminated:
struct Base {
Base(){}
Base(int){ throw int(5); }
};
struct Derived : public Base {
Derived(int a) noexcept : Base(a) {}
};
int main()
{
try{
Derived d(45);
} catch(...) {}
return 0;
}
Output:
terminate called after throwing an instance of 'int'
bash: line 7: 7454 Aborted (core dumped) ./a.out
See it Live on Coliru
But if you remove the noexcept specification, you wouldn't abruptly end your program, exception handling will continue normally. :-).
I'll leave you to think of the consequences if you do this kind of thing in production or even a large code base with many contributors. Do not use noexcept if you are unsure of the exception guarantees of all the statements in your function/constructor block
Yes, a noexcept on a constructor applies to base class/member construction.
If you need to deal with such a case, you probably want to use the little-known (and rarely used) function try block. The syntax looks something like this:
#include <iostream>
class bad_initializer {};
int do_throw() {
throw bad_initializer();
return 1;
}
class something {
int member;
public:
something() noexcept
try : member{do_throw()} // <-- initializer list
{
// ctor body goes here
}
catch(bad_initializer const &) {
std::cerr << "initialization threw\n";
}
};
int main() {
something s;
}
Now, the bad news: since you have a member that wasn't constructed, the catch block really has only a few options. Normal processing can't continue--an exception happened in constructing the object, which means the object can't ever finish construction. By the time you catch the exception, there's nothing you can do about that.
If it weren't noexcept, it could catch the exception, then do some processing (release any resources it did acquire successfully) then either rethrow the exception it caught, or throw a different exception (one that better reflected its inability to be constructed).
In this case, your meaningful choices are even more restricted: you can call terminate directly, or you can throw an exception, which will call terminate indirectly. About all the whole try/catch thing has done in this case is give you a chance to do a little processing before terminate gets called.
In general it's not okay, but in certain circumstances it may be
noexcept is a promise, similar to the const qualifier of member functions, but unlike const it's not enforced at compile time (the compiler will not issue an error and perhaps not even a warning, if a noexcept function may actually throw, but see below). Thus, you can declare a function noexcept even if a compiler-generated check would find that this function may throw and the code will compile (otherwise your question would be impossible).
However, that defeats the purpose of noexcept. The main purpose is to indicate (1) to the programmer that they can use a certain functionality without worrying about exception safety, and (2) to the compiler that it does not need to add code for stack unwinding. Instead, if an exception is thrown in a noexcept function, the run-time will invoke std::terminate(), as required by the standard.
So, in general your constructor should only be noexcept, if all its functionality, including the construction of bases and members is too.
However, there is an exception. If you know that some method will never throw given any input possible in the particular situation, even if it may throw under other circumstances and hence not be noexcept, you can call this method in a noexcept situation. For example,
// requires non-negative x, will throw std::runtime_error for negative x
int my_func(std::int64_t x);
struct my_struct {
std::int64_t q;
my_struct(int x) noexcept : q(std::int64_t(x)*std::int64_t(x)) {}
int member() const noexcept { return my_func(q); } // fine: q>=0
};
In the situation of your post, this means if member(somethingelse_type) is not noexcept, but you know (from conditions outside the code snipped in your post) that no exception will be thrown for the particular argument provided in this circumstance, you may declare Something(SomethingElse) noexcept.
Let's say I Have this:
namespace MyNamespace{
class Exception : public std::runtime_error
{
public:
explicit Exception(const std::string &msg) : std::runtime_error(msg) {}
};
} //namespace MyNamespace
And there is a code somewhere in my program:
try{
foo();
}
catch (const MyNamespace::Exception &exc){
std::cout << exc.what();
}
The question is (I want you to examine me) - will I catch the exception if I write in foo:
1) throw MyNamespace::Exception("Hello world!");
Here i think, yes, I will, because I definitely pointed out the type of exception(and it's necessary couse of "explicit" keyword) and std::string doesn't have "explicit" keyword which means I can throw "Hello world!" instead of std::string("Hello world!")
2) throw MyNamespace::Exception(std::string("Hello world!"));
obviosly, I will.
3) throw "Hello world!";
here i think, no, I won't, cause of keyword "explicit" presence.
4) throw std::string("Hello world");
no (same reason)
and 5) Whould I catch expections from the 3-4 cases if I didn't have explicit keyword? (I think yes)
update:
6) When the temporary object std::string will be created? At what point of time?
Your answers for 1-4 are correct, but the reasoning behind them is a little off.
3) This has nothing to do with explicit keyword. The type of the expression after throw is const char[12] and by the rules the type of the exception thrown is const char*.
4) Again, nothing to do with explicit string constructors, really. The type thrown is std::string and only std::string (with reference or not) type of handler can catch it.
5) So obviously, no.
6) When the exception is thrown.
From the wording in 3-5, you're obviously thinking that C++ attempts to match the throw to the catch statements as if it were picking the best match from overloaded functions to call. That's not the case. The throw statement is considered separately from any catch statements - indeed, you can compile the function foo and its throw statements before the catching code is written, so it can't choose to convert a std::string to some type the catching code ends up looking for... it might not know about that.
The type of value thrown depends entirely on the type of the parameter to throw, as it would be understood in the surrounding context if the expression appeared without throw. For example:
void foo()
{
...
throw XXX;
}
...throws the same type as...
void foo()
{
...
auto what_will_be_thrown = XXX;
throw what_will_be_thrown;
}
Conversions like const char* to std::string are not applied when catching, although you can catch a derived type via a public base class (for references or pointers), and of course you can catch types using const references etc..
Re 6) - whatever the type of the value, it's created just before the Exception constructor is called, just as any for any other function call timing wise, but in this case the object being thrown may be constructed in a separate memory area from the normal call stack, such that it will survive the stack unwinding that happens while looking for a matching catch statement. Exactly how this is orchestrated by the compiler is not specified in the Standard though.
Your rationale for 3 and 4 is wrong, and consequently, so is your answer to 5. Here’s why:
When you catch an exception, no conversion is every performed, except a conversion to base class. So catch (Foo const&) will never catch anything convertible to Foo, except subclasses of Foo. It’s for that reason, and not related to explicit constructors, that your code won’t catch a thrown std::string or char[].
I have 2 questions about non-throwing functions:
Why make a function non-throwing?
How to make a function non-throwing? If the code inside the function actually may throw, then should I still make it non-throwing?
Here is an example:
void swap(Type t1, Type t2) throw()
{
//swap
}
If the code in swap won't throw at all, should I still append throw()? Why?
throw() (or noexcept in C++11) is useful for two reasons:
It allows the compiler to be more aggressive in its optimisations.
It tells function users that they can use this function in their own non-throwing functions.
Non-throwing functions are very important for writing exception safe code. For instance, the usual way of writing an exception safe operator= is via a non-throwing swap() function.
On the other hand, other exception specifications are useless and have been justly deprecated in the current standard. They don't mix well at all with templates and are too expensive to enforce.
Now, if you use a noexcept specification in a function that might actually throw, all bets are off. Even if your compiler does not terminate the program when an exception leaves the function (VS does not do it for runtime efficiency reasons, for instance), your code might not do what you thought because of optimisations. For example:
void f() noexcept
{
a();
b();
}
If a() actually throws and b() has side effects, the function behaviour will be unpredictable, because your compiler may decide to execute b() before a(), since you have told it that no exceptions will be thrown.
EDIT: Now for the second part of your question: how to make a function non-throwing?
First you need to ask yourself whether your function should really be non-throwing. For instance:
class C
{
C* CreateInstance()
{
return new C();
}
}
Since operator new can throw a std::bad_alloc, CreateInstance() can throw. You could try to avoid it with a try-catch block, handling or swallowing any exceptions that may be thrown inside the try block, but would that really be sensible? For instance:
C* CreateInstance()
{
try
{
return new C();
}
catch (...)
{
return null;
}
}
Problem solved, it seems, but would your callers be prepared for CreateInstance() returning null? If not, a crash will ensue when they try to use that pointer. Besides, a std::bad_alloc usually means that you have run out of memory and you would just be postponing the problem.
So be careful: some functions can be made non-throwing, but others should be allowed to throw. Exception safety is not a trivial matter.
Why make a function non-throwing?
So callers of the function can call it without having to take any actions to deal with exceptions being raised by the function.
How to make a function non-throwing? If the code inside the function actually may throw, then should I still make it non-throwing?
You can make the code non-throwing by putting all code which could throw the inside a try block, and deal with any exceptions without re-throwing.
void swap(T t1, T t2) noexcept {
try {
// ....
} catch (const std::exception& ex) {
// ....
} catch (...) {
// ....
}
}
If you claim your function doesn't throw, then you have to make it non-throwing. But this doesn't mean adding an exception specification, which you shouldn't do anyway, since it is deprecated. It means you must ensure the function doesn't throw, no matter what. The C++11 keyword noexcept gives you some compile-time safety in this respect.
I have an exception class:
class MyException : public std::exception
{
public:
MyException( char* message )
: message_( message )
{
if( !message_ ) throw std::invalid_argument("message param must not be null");
}
};
And at my throw site:
try {
throw MyException( NULL );
}
catch( std::exception const& e ) {
std::cout << e.what();
}
(code was not compiled, so please excuse any errors)
I'm wondering what will happen when I throw from a constructor while constructing due to another throw. I assume this is legal, and the catch will end up catching a std::invalid_argument, and the previous exception thrown (MyException) will be ignored or cancelled out.
My goal with this design is to enforce invariants in my exception class. message_ should never be NULL, and I don't want to have if conditions to check if it is null in my what() overload, so I check them in the constructor and throw if they are invalid.
Is this correct, or is the behavior different?
The object you intend to throw (in this case MyException) must be successfully constructed before it can be thrown. So you're not throwing it yet, since it hasn't been constructed.
So this will work, throwing the exception from within MyException's constructor. You won't trigger the "throwing an exception while handling an exception causes std::terminate" issue.
15.1 Throwing an exception n3376
Paragraph 7
If the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught, calls a function that exits via an exception, std::terminate is called (15.5.1).
This means that until the constructor (of the object being thrown in this case) completes nothing special is going to happen. But after the constructor completes any other uncought exception will result in terminate() being called.
The standard goes on to provide an example:
struct C
{
C() { }
C(const C&) { throw 0; }
};
int main()
{
try
{
throw C(); // calls std::terminate()
}
catch(C) { }
}
Here terminate is called because the object is first created. But then the copy construction is called to copy the exception to the holding location (15.1.4). During this function call (copy construction) an uncaught exception is generated and thus terminate is called.
So your code as shown should work as expected.
Either: A MyException is generated with a good message and thrown
Or: A std::invalid_argument is generated and thrown
If you want to check invariants that should always be true, you should use assertions. Exceptions are meant for unusual situations that are expected to happen, like corner cases or bad user input.
If you use exceptions to report bugs in your code, you could accidentally hide them with catch(...). This is especially important if you are writing library code, because then you never know if other people might catch and ignore the exception, even if it means that the system has reached an invalid state.
Another advantage of assertions is that you can completely disable them if you want, such that they will no longer incur any performance penalties. This allows you to be really paranoid with those checks in your debug builds and still have a lightning fast release build.