I have run into broken compiler, which does not allow exceptions to inherit from std::exception (nvcc 3.0).
so had to create workaround:
struct exception {
explicit exception(const char* message) {
what_ = message;
}
virtual const char *what() const throw() { return what_; }
operator std::exception() const {
return std::runtime_error(what_);
}
private:
const char* what_;
};
struct configuration_error : exception {
configuration_error(const char* message)
: exception(message) {}
};
is there something I am going to lose by not inheriting from exception, instead providing cast? is what necessary in the above case?
thank you
catch (std::exception) will not catch your exception, and you cannot dynamic_cast your exception to std::exception either. If your program never does either of those things, you're fine.
Personally I would not use a compiler this broken, though.
You should upgrade to CUDA 3.1.
If you're trying to create an instance of something derived from std::exception on the device, it won't work because the std::exception constructor would need to be called, and that is not a device function.
Throwing and catching your own type is probably the solution. Since it probably will never make it back to host code, though (C++ doesn't really handle throwing multiple exceptions in parallel), compatibility with std::exception shouldn't be too much of an issue.
Related
In a code review recently, I had some less than kind words for something I thought awful. It turns out that it was obviously inspired by the QuantLib::Error class, which looks like this:
//! Base error class
class Error : public std::exception {
public:
/*! The explicit use of this constructor is not advised.
Use the QL_FAIL macro instead.
*/
Error(const std::string& file,
long line,
const std::string& functionName,
const std::string& message = "");
#ifdef QL_PATCH_MSVC_2013
/*! the automatically generated destructor would
not have the throw specifier.
*/
~Error() throw() override {}
#endif
//! returns the error message.
const char* what() const QL_NOEXCEPT override;
private:
ext::shared_ptr<std::string> message_;
};
Why is the member variable ext::shared_ptr<std::string> and not just plain std::string? What reason could there be to heap-allocate the string object itself? (The QuantLib code base seems to heap-allocate just about everything just about always just about everywhere, and pulls in shared_ptr's to cope with that - a classic anti-pattern - but doing it here as well "just for consistency" strikes me as a bit much. Am I missing something?)
This is following the behavior of standard library exception types.
They are supposed to be copyable without throwing exceptions, since throwing an exception during construction of an exception handler parameter would cause a call to std::terminate (and possibly in some other situations requiring a copy of the exception as well).
If std::string was used directly, copying the exception could cause for example a std::bad_alloc to be thrown. Using a reference-counted pointer instead avoids that.
I am beginner in c++, and hence apologies for this silly question. I am posting it here because I cannot find a similar answer on stackoverflow.
I was progressing through exceptions in C++ and as I was doing some hands on with custom exceptions, I have this code
class MyException: public std::exception{
public:
virtual const char* what() const throw() {
return "something bad happened";
}
};
// class that throws above exception
class canGoWrong {
public:
canGoWrong(){
throw MyException();
}
};
The above code was shown by the teacher. The constructor just implemented a virtual function defined in the base class exception. I got till there.
Now when I was trying a different version to practice, I tried to use a custom function instead of re-defining the virtual (as c++ doesn't strictly enforce the concept of interface, please correct me if I am wrong here.)
I wrote it as
class my_custom_shit_exception: public std::exception {
public:
const char* show() { // I omitted the const throw() here
return "This is an error encountered\n";
}
};
class myclass {
public:
myclass() {
throw my_custom_shit_exception();
}
};
To summarise, I didn't find a difference in behaviour in both ways
public:
const char* show() {
return "This is an error encountered\n";
}
virtual const char* what() const throw() {
return "something bad happened";
}
So why was the const throw() used in the what() virtual function? What difference it makes?
Thanks to all.
The function signature
class std::exception {
//...
public:
virtual const char* what() const throw();
//...
};
can be read as: what is a virtual member function of std::exception which returns a pointer to a constant character (array) and which does not modify members of that object (hence the 2nd const) and which guarantees not to throw an exception in its code.
Beware that the exception-specification is nowadays deprecated: Instead, since C++11 there is the noexcept specifier to declare functions that "guarantee" not to throw exceptions. Additionally, since C++17 the throw() has become a synonym for noexcept(true), but with a slightly different behaviour.
For more details, refer to this description of noexcept.
There it also says: "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. The compiler can use this information to enable certain optimizations on non-throwing functions [...]".
I wanted to show some quotes from Scott Meyers
"Effective C++" Third Edition
int doSomething() throw(); // note empty exception spec.
This doesn’t say that doSomething will never throw an exception; it
says that if doSomething throws an exception, it’s a serious error,
and the unexpected function should be called. †
For information on the unexpected function, consult your favorite search engine or
comprehensive C++ text. (You’ll probably have better luck searching for set_unexpected,
the function that specifies the unexpected function.)
And from the "Effective Modern C++"
In C++11, unconditional noexcept is for functions
that guarantee they won’t emit exceptions.
If, at runtime, an exception leaves f, f’s exception specification is violated. With the
C++98 exception specification, the call stack is unwound to f’s caller, and, after some
actions not relevant here, program execution is terminated. With the C++11 exception specification, runtime behavior is slightly different: the stack is only possibly
unwound before program execution is terminated.
The difference between unwinding the call stack and possibly unwinding it has a surprisingly large impact on code generation. In a noexcept function, optimizers need
not keep the runtime stack in an unwindable state if an exception would propagate
out of the function, nor must they ensure that objects in a noexcept function are
destroyed in the inverse order of construction should an exception leave the function.
Functions with “throw()” exception specifications lack such optimization flexibility,
as do functions with no exception specification at all.
I was playing with c++ exceptions and I've tried throwing an anonymous exception like this:
throw class : public std::exception
{
virtual const char *what() const noexcept
{
return "Custom exception";
}
} ex;
However I'm getting the following error when trying to compile:
error: expected primary-expression before ‘class’
throw class : public std::exception
^
My compiler is gcc 5.2.1 on Linux x86_64.
How can I achieve the desired result?
This is not an answer per-se, but some important information what will help you going forward:
First, throwing an anonymous exception is unlikely to be useful. Exceptions are caught by their type. If you can't name the type, you can't catch the exception explicitly - only by its base, in which case you may as well have just thrown the base.
Second (and this is important):
There's rarely a good reason to derive from std::exception directly. You should derive from one of the exception types defined in <stdexcept>
these are:
std::runtime_error - indicating that some runtime condition makes it impossible to perform the service at the moment (such as a missing file).
std::logic_error - indicating that what was attempted will never be possible and the program is fundamentally in error in a way that could not be detected at compile time.
Handy reference here:
http://en.cppreference.com/w/cpp/header/stdexcept
You can't declare a class in a throw statement. Declare the class first (anonymously if you like, naming it via a typedef), then you can throw it.
Better is to name the exception class, but put it in the nameless namespace:
namespace {
class LocalException : public std::exception {
const char *what() const noexcept override {
return "Custom exception";
}
};
}
....
throw LocalException();
or, if you insist, you can create an object of anonymous class, and throw that.
static class : public std::exception {
const char *what() const noexcept override {
return "Custom exception";
}
} LocalExceptionObject;
....
throw LocalExceptionObject;
Edit If you create a typedef, somebody can copy it, and it names the same class. You have to create an object of the anonymous class, and then nobody can name it.
Having said that, I don't think having anonymous things is useful. Far better to declare the class in a nameless namespace (so you know it is private), and just use it.
I'm trying to write an exception class that needs to be thrown when a system call fails. The exception should have a developer message and the errno code, and it's what method should format the developer message along with the error code. The C way to do the formatting is snprintf, but I'm trying to avoid that. I tried defining a class member for the exception of type std::stringstream. However, that did not work since stringstream has a private copy constructor. Looking for an alternative I learned about Boost's format object. I tried using it and got a different error:
In file included from tun_device.cc:7:0:
system_error.h:9:7: error: looser throw specifier for ‘virtual SystemError::~SystemError()’
class SystemError : public exception
^
In file included from system_error.h:4:0,
from tun_device.cc:7:
/usr/include/c++/4.8/exception:64:13: error: overriding ‘virtual std::exception::~exception() throw ()’
virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
The way to solve this was to define my own destructor:
~SystemError() throw() {
}
As I understand, this line specifies that the destructor of this exception should not throw any exceptions.
Here's the complete class:
class SystemError : public exception
{
public:
int m_errno;
const char * m_message;
SystemError(int err, const char * message) :
fmt("%1%: %2%") {
fmt % message % errno;
m_errno = err;
this->m_message = message;
}
const char * what() const throw(){
return fmt.str().c_str();
}
~SystemError() throw() {
}
private:
format fmt;
};
I have several questions:
First of all - Am I reinventing the wheel? Is already there a recommended C++ way to handle failed system calls?
Why does using the format class as a member of the exception forces me to override the default destructor?
Is there any pitfall I should be aware of now that I added my own destructor?
Is there a way to achieve what I want using only the standard C++ library?
Exception can be handled using the standard exception class or creating your own classes derived from std::exception class. Inheritance would be used when you would want to extend the already available functionality available using std::exception. So the decision is totally dependent on how you want design your application.
boost::format does not force you to override the destructor. If you notice you are deriving from std::exception and composing boost::format. std::exception destructor is declared as virtual and has a no throw nature.
virtual ~exception() throw();
When you leave out the destructor, compiler implicitly provides a destructor, but this destructor does not have no throw() nature, hence compile error:
format.cpp:5: error: looser throw specifier for âvirtual SystemError::~SystemError()â
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:63: error: overriding âvirtual std::exception::~exception() throw ()â
When you provide a constructor but as:
~SystemError(); //since the base class std::exception has a destrutor with no throw, the child should also follow the same, and again in this case compile time error is received:
format.cpp:25: error: looser throw specifier for âvirtual SystemError::~SystemError()â
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:63: error: overriding âvirtual std::exception::~exception() throw ()â
To resolve the error SystemError should define a destructor like this:
~SystemeError() throw();
Sample SSCCE code:
#include <iostream>
#include<boost/format.hpp>
class SystemError : public std::exception
{
public:
int m_errno;
const char * m_message;
SystemError(int err, const char * message) :
fmt("%1%: %2%") {
fmt % message % err;
m_errno = err;
this->m_message = message;
}
const char * what() const throw(){
return fmt.str().c_str();
}
~SystemError() throw() {
}
// ~SystemError() {
//
// }
private:
boost::format fmt;
};
int main(){
return 0;
}
Adding destructor is like taking responsibilities of your actions. Destructor could be used to clear any heap memory assigned in the class. Absence of destructor would lead compiler to provide an implicit destructor, which could be cause of issues in specific cases.
The compilation error will not be received if the class in discussion has primitive data types.
I'm writing a function, wd_sprintf, to provide a sprintf-like API. Under the covers, it uses the boost library.
If the user of wd_sprintf codes the format string improperly, boost::format will throw an exception. I'd like for my function to intercept the exception, repackage it in a message that identifies wd_sprintf as the locus of the error, and rethrows the exception.
What I can't figure out is what to catch, and how to extract the message.
// wd_sprintf(pattern [,args...]):
//
// This creates a temporary boost::format from pattern, and calls
// wd_sprintf_r() to recursively extract and apply arguments.
#include <boost/exception/all.hpp>
class wd_sprintf_exception : std::runtime_error {
public:
wd_sprintf_exception(string const& msg : std::runtime_error(msg) {}
};
template <typename... Params>
string
wd_sprintf (const string &pat, const Params&... parameters) {
try {
boost::format boost_format(pat);
return wd_sprintf_r(boost_format, parameters...);
}
catch (boost::exception e) {
const string what = string("wd_sprintf: ") + string(e.what());
throw wd_sprintf_exception(what);
}
}
Of course, this gets a compilation error because boost::exception is abstract.
(I've been to a number of sites and pages, including this one whose title was similar but which was full of '<<' operators inserting into a function call, template constructs like boost::get_error_info<my_tag_error_info>(e), and generally much more complexity than I suspect is really needed. I just need the above to work.)
You can't have an an automatic variable of an abstract type. You can, however, have a reference or pointer to one. The reason for this is that the compiler has no way of knowing exactly which derived type the variable actually is, so it doesn't know how much space to allocate for it or which class's copy constructor to use.
When you catch a boost::exception by value, as you're doing, the compiler has to make a local copy of it in your catch block; which it doesn't have enough information to do!
In your specific case, the best solution is to catch a reference to the original exception.
In regards to catching exceptions from Boost.Format, it throws exceptions derived from boost::io::format_error, which is derived from std::exception, not boost::exception. You should be catching boost::io::format_error.