Type casting in exceptions - c++

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[].

Related

what is std::exception::what() and why to use it?

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.

Can a noexcept function still call a function that throws in C++17?

In P0012R1, "Make exception specifications be part of the type system",
I see that noexcept is now becoming a part of the function type.
I can't tell whether this will prevent noexcept(true) functions from still being able to call noexcept(false) functions.
Will the following code still be valid for C++17?
void will_throw() noexcept(false){
throw 0;
}
void will_not_throw() noexcept(true){
will_throw();
}
According to cppreference:
Note that a noexcept specification on a function is not a compile-time
check; it is merely a method for a programmer to inform the compiler
whether or not a function should throw exceptions.
So the syntax of your code is valid, but std::terminate will be called when executed.
Unfortunately it is valid at compile time.
Although noexcept is used by the compiler to optimize the exception handling code, making the code more performant, it's a shame they didn't push it further to give noexcept a semantic meaning.
Ideally, when you mark a method as noexcept it should also mean that the method is not supposed to let any exceptions bubble up. So if you have a method marked as noexcept but it calls other methods that are not marked as noexcept, that should give you a compile error, unless there is a try/catch block surrounding anything that can throw.
Simply calling std::terminate is a very poor language design choice, because it doesn't put any responsibility at the hands of whoever writes the noexcept method. On the contrary, it harms software reuse by making it impossible even to the consumer to work the problem around.
For example, say that I am a bad library developer and I wrote the following code:
Header file Foo.h that ships with my library:
class Foo
{
public:
void DoSomething() noexcept;
};
You are happy consumer of FooLib writing a Bar application:
Bar.cpp
#include "Foo.h"
int main()
{
Foo foo;
try
{
foo.DoSomething();
}
catch (...)
{
std::cout << "Yay!" << std::endl;
}
return 0;
}
That code compiles fine and runs fine until you have Foo throwing an exception... And it doesn't make any difference if you enclose the call to foo.DoSomething() with a try/catch block. The code will simply abort.
If you don't have the code of Foo, you can't fix it. The only solution in this case is to throw away Foo library and write your own.
The contents of Foo.cpp can be something like this:
static void PotentiallyThrowException()
{
throw 0;
}
void Foo::DoSomething() noexcept
{
PotentiallyThrowException();
}
Note that it's up to the implementer of Foo::DoSomething() to wrap their own calls into try/catch. But due to the same issue, if they are calling other methods that are marked as noexcept and those developers didn't do the same, now it's Foo::DoSomething() that is hosed. And so on, and so forth.
We can safely say that from the semantic point of view noexcept is not only useless, but it's also harmful.
noexcept(true) functions can call noexcept(false) functions. There will be a runtime error if an exception is thrown. The canonical example of why this is allowed is:
double hypotenuse(double opposite, double adjacent) noexcept(true)
{
return std::sqrt(opposite*opposite + adjacent*adjacent);
}
std::sqrt will throw domain_error if its argument is negative, but clearly that will never happen here.
(In an ideal world, it would be forbidden by default with an exception_cast to allow it where required. The result could either be UB if an exception is thrown, or std::terminate).
Including the exception specification in the function type is orthogonal to whether a function can call another function with an incompatible exception specification (without handling the exceptions that were not included in its exception specification). The former is about type safety with respect to function pointers (so that you cannot call a throwing function through a function pointer that was known not to throw). Regarding the latter, we can either prohibit it during compilation (as in Java), or treat it as a runtime error (leading to the termination of the program, as is chosen for the C++ current standard).
One may argue by brining the analogy of calling a non-const (non-static) member function from a const (non-static) member function. However the difference is that indirectly modifying an object inside a non-const member function called through a const member function would go undetected (or else would be too costly to detect) and may lead to nasty bugs, that's why it has to be prevented during compilation. Whereas the act of throwing an exception is (should be) an exceptional event and we can afford inserting run-time checks of whether the exception complies with the exception specification and should be let out, or it violates the program logic and should instead terminate the program.

Does noexcept apply to exceptions propagating from initializer lists

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.

Exception slicing - is this due to generated copy constructor?

I've just fixed a very subtle bug in our code, caused by slicing of an exception, and I now want to make sure I understand exactly what was happening.
Here's our base exception class, a derived class, and relevant functions:
class Exception
{
public:
// construction
Exception(int code, const char* format="", ...);
virtual ~Exception(void);
<snip - get/set routines and print function>
protected:
private:
int mCode; // thrower sets this
char mMessage[Exception::MessageLen]; // thrower says this FIXME: use String
};
class Derived : public Exception {
public:
Derived (const char* throwerSays) : Exception(1, throwerSays) {};
};
void innercall {
<do stuff>
throw Derived("Bad things happened!");
}
void outercall {
try {
innercall();
}
catch(Exception& e)
{
printf("Exception seen here! %s %d\n", __FILE__, __LINE__);
throw e;
}
}
The bug was of course that outercall ends up throwing an Exception, instead of a Derived. My bug resulted from higher in the call stack attempts to catch the Derived failing.
Now, I just want to make sure I understand - I believe that at the 'throw e' line, a new Exception object is being created, using a default copy constructor. Is that what's really going on?
If so, am I allowed to lock out copy constructors for objects that will be thrown? I'd really prefer this not happen again, and our code has no reason to copy Exception objects (that I know of).
Please, no comments on the fact that we have our own exception hierarchy. That's a bit of old design that I'm working to correct (I'm making good progress. I've gotten rid of the home-grown string class, and many of the home-grown containers.)
UPDATE: To be clear, I had fixed the bug (by changing 'throw e' to 'throw') before I ever asked the question. I was just looking for confirmation of what was going on.
When you throw an object, you're actually throwing a copy of the object, not the original. Think about it - the original object is on the stack, but the stack is being unwound and invalidated.
I believe this is part of the standard, but I don't have a copy to reference.
The type of exception being thrown in the catch block is the base type of the catch, not the type of the object that was thrown. The way around this problem is to throw; rather than throw e; which will throw the original caught exception.
A quick google suggests that yes, you're throwing the copy constructor is required and must be public. (Which makes sense, as you're initializing a copy of e and throwing that.)
Anyway, just use throw without specifying the exception object, to rethrow what was caught in the catch. Shouldn't that solve the problem?
catch(Exception& e)
{
printf("Exception seen here! %s %d\n", __FILE__, __LINE__);
throw;
}
Yes.
throw e;
throws an exception of the static type of e, regardless of whatever e actually is. In this case, the Derived exception is copied to an Exception using a copy constructor.
In this case you can just
throw;
to get the Derived exception bubble up correctly.
If you're interesting in polymorphical throwing in some other cases, refer to the always so useful C++ FAQ Lite.
C++ never ceases to amaze me. I would have lost a lot of money had this been a bet on what was the behaviour!
The exception object is first copied to a temporary and you should have used throw. To quote the standard 15.1/3:
A throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from "array of T" or "function returning T" to "pointer to T" or "pointer to function returning T",respectively.
I think this gives rise to a very useful coding standard rule:
Base classes of an exception hierarchy should have a pure virtual destructor.
or
The copy constructor for a base class in an exception hierarchy shall be protected.
Either achieves the goal that the compiler will warn when you try to "throw e" since in the first case you cannot create an instance of an abstract class and the second because you cannot call the copy constructor.

Catching exceptions polymorphically

Here is main():
int main()
{
B b(1,"two","three");
try
{
f1(b);
}
catch(B& b_ref)
{
cout<<"Caught B&"<<endl;
b_ref.print();
}
catch(A& a_ref)
{
cout<<"Caught A&"<<endl;
a_ref.print();
}
system("pause");
return 0;
}
Here is f1():
void f1(A& subject)
{
throw subject;
}
Information:
B inherits from A. A::print() is virtual, and is reimplemented in B. The catch that catches the exception is catch(A& a_ref), which I guess makes sense, since the exceptions' static type (subject) is A&. BUT, why isn't B:: print() running? Is the dynamic type "lost"? Only A::print() runs in the line a_ref.print();.
Can somebody explain?
throw only throws an object of the type of the expression which follows it. In this case, subject is of type A&, regardless of what the actual object is, so an A is thrown (note that references cannot be thrown, so a copy is made).
You can deal with this by adding a member function to your exception classes which throws the exception. As long as you implement this method in every class, the override which gets called will know the runtime type of the object and can throw *this.
http://www.ddj.com/cpp/184401940
According to C++ standard 15.1/3:
A throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw...
So you create temporary object of type A, not B.
When you say "throw subject" a new exception object is created based on the static type of the throw expression (subject). The fact that subject is a reference is irrelevant for the purposes of determining what object to throw. A new A object is copy constructed from subject. This copy (or possibly a copy of this copy) is the actual object that is caught.
Catch blocks work polymorphically, but throw doesn't. When you say:
void f1(A& subject)
{
throw subject;
}
you are throwing an A, although the thing passed to the function is a B.
Because you catch by reference the object is 'sliced'.
If you really want polymorhpic behaviour, try using something like the pimpl idiom.