My code throws std::runtime_error, but doesn't catch it in the catch block. Instead it just calls std::terminate or, if I declared an exception-specifier on a function, calls std::unexpected.
The code simplifies down to:
void myfunc()
{
throw new std::runtime_error("always throw");
}
int main()
{
try {
myfunc();
} catch (std::runtime_error &err) {
std::cerr << "intentionally ignored exception: " << err.what() << std::endl;
return 0;
}
std::cerr << "unreachable?" << std::endl;
return 1;
}
Similarly, if I add a throw specifier on my function, I crash out with std::unknown.
void myfunc() throw (std::runtime_error)
{
throw new std::runtime_error("always throw");
}
You slipped in a Java-ism:
throw new std::runtime_error("always throw")
^^^
This causes the catch clause not to match, because it matches by type and you throw std::runtime_error*, i.e. a pointer to a std::runtime_error. It's expecting a plain std::runtime_error by-reference.
You could (untested) catch your original exception with
catch (std::runtime_error * exc) /* don't do this */
but you shouldn't do that.
Instead skip the new; throw your exception directly and write:
void myfunc()
{
throw std::runtime_error("always throw");
}
C++ is smart enough that if you catch the exception by-reference it won't get copied around.
Also, as #KonradRudolph points out in the comments, you should catch by const-reference:
catch (const std::runtime_error &err)
Related
I want to set a global exception handler in C++. With a hook, any exceptions (of a specified type) thrown, would be caught by the handler. With this, I could do a little pretty printing before the exception kills the program, or maybe I could write everything to a log file.
boost seems to have an exception handler hook. This seemed extremely promising, but the code provided didn't work as I thought it should. Am I missing something?
struct my_handler
{
typedef void result_type;
void operator() (std::runtime_error const& e) const
{
std::cout << "std::runtime_error: " << e.what() << std::endl;
}
void operator() (std::logic_error const& e) const
{
std::cout << "std::logic_error: " << e.what() << std::endl;
throw;
}
};
void init_exception_handler()
{
// Setup a global exception handler that will call my_handler::operator()
// for the specified exception types
logging::core::get()->set_exception_handler(logging::make_exception_handler<
std::runtime_error,
std::logic_error
>(my_handler()));
}
// The above is all code from the boost doc example. Untouched.
int main(int argc, char* argv[]) {
init_exception_handler();
// I can throw now right...?
throw std::runtime_error("This should be suppressed!");
return 0;
}
In this code, the runtime_error I throw is not suppressed even though I thought I had setup the exception handler.
I'd like to catch an exception while trying to use copy constructor of some class, which would throw.
#include <iostream>
class dont_copy_me {
public:
dont_copy_me() {}
dont_copy_me(const dont_copy_me& rhs) {throw;}
dont_copy_me(dont_copy_me&& rhs) {throw;}
~dont_copy_me() {}
};
int main() {
try {
dont_copy_me obj;
dont_copy_me obj_1(obj);
} catch(...) {
std::cout << "exception caught" << std::endl;
}
return 0;
}
But I keep getting
terminate called without an active exception
Aborted (core dumped)
What is wrong? How do I catch the exception thrown by copy constructor? (because that's what I need)
Actually throw an exception like this:
#include <iostream>
#include <stdexcept>
class dont_copy_me {
public:
dont_copy_me() {}
dont_copy_me(const dont_copy_me& rhs) {throw std::runtime_error("Fail!");}
dont_copy_me(dont_copy_me&& rhs) {throw std::runtime_error("Fail!");}
~dont_copy_me() {}
};
int main() {
try {
dont_copy_me obj;
dont_copy_me obj_1(obj);
} catch(...) {
std::cout << "exception caught" << std::endl;
}
return 0;
}
This does what you need. Here you can find a list of standard exceptions (under "Exception categories").
The empty throw expression only works when you are already handling an active exception:
Rethrows the currently handled exception. Abandons the execution of the current catch block and passes control to the next matching exception handler (but not to another catch clause after the same try block: its compound-statement is considered to have been 'exited'), reusing the existing exception object: no new objects are made. This form is only allowed when an exception is presently being handled (it calls std::terminate if used otherwise). The catch clause associated with a function-try-block must exit via rethrowing if used on a constructor.
From here, emphasis mine.
Your catch (...) block is fine, the problem is your program does not throw an exception.
There are two forms of throw expression:
throw <some-exception> create and throw an exception
throw re-throw the current exception
In your code, you are calling the second form from your copy constructors. Use the first form instead.
The second form is used when you want to some partial handling of an exception. Here's a contrived example program that uses both forms:
#include <cstdexcept>
#include <cstdlib>
#include <iostream>
int main()
{
int ret = EXIT_FAILURE ;
try
{
try
{
throw std::logic_error("Fail!"); // form 1
ret = EXIT_SUCCESS;
}
catch (...)
{
std::clog << "re-throwing" << std::endl;
throw; // form 2
}
}
catch (...)
{
std::cerr << "unhandled exception" << std::endl;
}
return ret;
}
See: http://en.cppreference.com/w/cpp/language/throw
This is about wrapping the exception handling logic in some sort of class. While writing c++
code, many time we need to catch many type/variants of exception depending on what client throw. This lead us to write similar types of code(many times) in catch() clause.
In below sample example, I have written the function(), which can throw exception in the many possible form.
I wanted to know is it possible to write/wrap such logic in the form of class so that end user would have to write similar types of code at once place?. Does it make any sense or it has any meaning?
#include<vector>
#include<string>
#include<exception>
#include<iostream>
// this function can throw std::exception, std::string, int or unhandled
void function() {
std::vector<int> x{1,2,3,4,5};
auto val = x.at(x.size()); //throw out-of-range error
}
int main() {
try { function(); }
catch(std::exception& e) { std::cout<<e.what()<<std::endl; }
catch(std::string& msg) { std::cout<<msg<<std::endl; }
catch(int i) { std::cout<<i<<std::endl; }
catch(...) { std::cout<<"Unhandled Exception"<<std::endl; }
return 0;
}
So far I thought in this way and below is the pseudo logic.
class exceptionwrapper{
exceptionwrapper(function pointer* fp) {
// functions which would be executing inside try
}
~exceptionwrapper() {
// all catch() clause can be written over here
// or some other member function of this class
}
};
The object of this class can be instantiated in the main() in this way.
int main() {
exceptionwrapper obj(function);
//here execptionwrapper destructor would take care about calling all type of catch
}
It is possible using std::exception_ptr:
Live demo link.
#include <iostream>
#include <exception>
#include <stdexcept>
void universal_exception_handler(std::exception_ptr e)
{
try
{
std::rethrow_exception(e);
}
catch (const std::logic_error& e)
{
std::cout << "logic_error" << std::endl;
}
catch (const std::runtime_error& e)
{
std::cout << "runtime_error" << std::endl;
}
}
void foo()
{
throw std::logic_error{""};
}
void bar()
{
throw std::runtime_error{""};
}
int main()
{
try
{
foo();
}
catch (...)
{
universal_exception_handler(std::current_exception());
}
try
{
bar();
}
catch (...)
{
universal_exception_handler(std::current_exception());
}
}
You can also achieve this without std::exception_ptr, just put throw; in place of std::rethrow_exception(e);, hoping this function will be invoked only if there is an active exception being handled (otherwise your program will be terminate()'ed):
void universal_exception_handler()
{
try
{
throw;
}
catch (const std::logic_error& e)
{
std::cout << "logic_error" << std::endl;
}
catch (const std::runtime_error& e)
{
std::cout << "runtime_error" << std::endl;
}
}
try
{
foo();
}
catch (...)
{
universal_exception_handler();
}
Yet another live demo link.
What you're asking for is possible, but I don't think it's very useful. First let's implement a mechanism to accept a callable object, and its associated arguments, which we'll invoke in the destructor of exception_wrapper.
template<typename Func, typename... Args>
struct exception_wrapper
{
exception_wrapper(Func f, Args... args)
: f_(std::move(f))
, args_(std::make_tuple(std::move(args)...))
{}
~exception_wrapper()
{
try {
invoke();
} catch(std::exception const& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
} catch(...) {
std::cerr << "Caught unknown exception" << std::endl;
}
}
template<std::size_t... I>
void apply(std::index_sequence<I...>)
{
f_(std::get<I>(args_)...);
}
void invoke()
{
apply(std::index_sequence_for<Args...>());
}
Func f_;
std::tuple<Args...> args_;
};
template<typename Func, typename... Args>
auto make_exception_wrapper(Func&& f, Args&&... args)
{
return exception_wrapper<Func, Args...>(
std::forward<Func>(f), std::forward<Args>(args)...);
}
This makes use of the C++14 std::integer_sequence; if that's not available on your implementation there are several answers on SO that show how to implement it yourself (this one for instance).
To use it, create an exception_wrapper object, and your function will be invoked when the destructor executes.
make_exception_wrapper(function);
Live demo
Now, I don't think this is useful because in general you should only catch exceptions if your code is able to handle them, and continue operating normally. Otherwise let them propagate to the top level where you might want to install a handler so it allows you to exit the program gracefully.
Given that, it's unlikely that there'll be a common approach to handling all exceptions thrown by your code, which greatly reduces the utility of exception_wrapper as implemented. You could modify it to take another callable argument, the exception handler that will be passed the std::exception object that was caught, which makes the class a little more generic.
Additionally, invoking the function in the destructor means you cannot pass the return value, if any, back to the caller. This can be fixed by invoking the function within exception_wrapper::operator() instead, but that then adds the wrinkle of what to return in the case an exception is indeed thrown, and you've suppressed it.
Finally, do not write code that throws types that are not derived from std::exception. This makes your code unidiomatic, and if you do want to handle the exception, you'll need to litter the code with several catch statements, like you have in your example.
I have a function using try-catch. so I want use and another class to print out different kind of messages. What should I do?
I use namespace std. I'm new at this an not familiar with using namespace std. Please guide me thanks.
SparseException::SparseException ()
{ }
SparseException::SparseException (char *message)
{ }
void SparseException::printMessage () const
{
// ...
}
try
{
//did some stuffs here.
}
catch (exception e)
{
char *message = "Sparse Exception caught: Element not found, delete fail";
SparseException s (message);
s.printMessage();
}
Derive your exception class from std::exception and override what(). Remove your function printMessage and implement (override):
virtual const char* what() const throw();
In C++11 this function has this signature:
virtual const char* what() const noexcept;
Then your catch clause and printing of exception's reason can look like this:
catch (const std::exception& e)
{
std::cerr << "exception caught: " << e.what() << '\n';
}
Or if you are going to throw only your exception, you can simply do this:
SparseException::SparseException ()
{ }
SparseException::SparseException (char *message)
{ }
void SparseException::printMessage () const
{
// ...
}
try
{
//did some stuffs here.
//Possibly
//throw SparseException();
//or
//throw SparseException("Some string");
//Make sure you can throw only objects of SparseException type
}
catch (SparseException e)
{
e.printMessage();
}
If the line with throw is executed, the result of try block will be terminated and the catch block will execute, where e is the object you have thrown.
I have a silly question. I read this article about std::exception http://www.cplusplus.com/doc/tutorial/exceptions/
On catch (exception& e), it says:
We have placed a handler that catches exception objects by reference (notice the ampersand & after the type), therefore this catches also classes derived from exception, like our myex object of class myexception.
Does this mean that by using "&" you can also catch exception of the parent class? I thought & is predefined in std::exception because it's better to pass e (std::exception) as reference than object.
The reason for using & with exceptions is not so much polymorphism as avoiding slicing. If you were to not use &, C++ would attempt to copy the thrown exception into a newly created std::exception, potentially losing information in the process. Example:
#include <stdexcept>
#include <iostream>
class my_exception : public std::exception {
virtual const char *what() const throw() {
return "Hello, world!";
}
};
int main() {
try {
throw my_exception();
} catch (std::exception e) {
std::cout << e.what() << std::endl;
}
return 0;
}
This will print the default message for std::exception (in my case, St9exception) rather than Hello, world!, because the original exception object was lost by slicing. If we change that to an &:
#include <stdexcept>
#include <iostream>
class my_exception : public std::exception {
virtual const char *what() const throw() {
return "Hello, world!";
}
};
int main() {
try {
throw my_exception();
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
}
return 0;
}
Now we do see Hello, world!.
Does this mean that by using "&" you can also catch exception of the parent class?
No, this doesn't increase the scope of where you will catch exceptions from (e.g. from the parent class of the class that contains the try/catch code).
It also doesn't increase the types of exceptions that can be caught, compared to catching by value (catch(std::exception e) without the & - you'll still catch each exception that either is std::exception or derives from it).
What it increases is the amount of data that you will actually get when you catch the exception.
If an exception is thrown that derives from std::exception, and you catch it by value, then you are throwing out any extra behavior in that exception class. It breaks polymorphism on the exception class, because of Slicing.
An example:
class MyException : public std::exception
{
public:
virtual const char* what() const
{
return "hello, from my exception!";
}
};
// ...
try
{
throw MyException();
}
catch(std::exception& e)
{
// This will print "hello, from my exception!"
std::cout << e.what() << "\n";
}
// ...
try
{
throw MyException();
}
catch(std::exception e)
{
// This will print "Unknown exception"
std::cout << e.what() << "\n";
}
No the & has absolutely no bearing on the polymorphic nature of exception handlers. Their wording is very poor, it does seem to indicate that the & is somehow responsible. This is not the case. You are correct, & just passes by reference which is a tad more efficient.
Also as a general rule, you should really try to avoid cplusplus.com.
Updated link: What's wrong with cplusplus.com
Using reference to exception here can reduce the temporary objects created, and it can also keep the polymorphism.