I came across the following code on VS2008
if (!CreateProcess( NULL,
const_cast<LPWSTR>(ss.str().c_str()),
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW|NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi))
{
throw std::exception("Unable to format Device");
}
Now I am porting the code to mingw gcc and I get the error
error: no matching function for call to 'std::exception::exception(const char [23])'
Investigating the issue I noticed that Visual Studio has a file exception which does have an exception class and does take in char*. Some of the definitions look like this
__CLR_OR_THIS_CALL exception();
__CLR_OR_THIS_CALL exception(const char *const&);
__CLR_OR_THIS_CALL exception(const char *const&, int);
__CLR_OR_THIS_CALL exception(const exception&);
exception& __CLR_OR_THIS_CALL operator=(const exception&);
virtual __CLR_OR_THIS_CALL ~exception();
virtual const char * __CLR_OR_THIS_CALL what() const;
My question is how should I circumvent this build issue on mingw gcc ? Should I create a new class that inherits from std::runtime_error and throw that instead ?
Opinion plays a role here. The problem is that std::exception does not have a constructor that takes a string argument; this is an MSVC extension. I see two ways to go about it:
Don't pass a string argument
Don't use std::exception
The first case is straightforward; just use
throw std::exception();
The drawback is that you don't get a descriptive error message.
If the error message is important, using std::exception directly is not an option. In this case, you could use either std::logic_error or std::runtime_error, which inherit std::exception and do have constructors taking a string argument, so
throw std::runtime_error("Unable to format Device");
might already solve the problem. catch clauses that caught the std::exception will also catch the std::runtime_error. There is one potential problem, though: catch clauses that catch std::runtime_error would not have caught the std::exception but will catch this one.
This seems like a bit of a corner case, and it is entirely possible that it is not a problem for you. If, however, there is a possibility that along the call stack there is a catch clause that catches std::runtime_error but should not catch the exception thrown by this code, you could derive your own exception class from std::exception that does take a string argument. Because the class is new, it will not be caught by existing catch clauses. For example:
class descriptive_exception : public std::exception {
public:
descriptive_exception(std::string const &message) : msg_(message) { }
virtual char const *what() const noexcept { return msg_.c_str(); }
private:
std::string msg_;
}
And then
throw descriptive_exception("Unable to format Device");
This is arguably not very pretty, and it is unlikely that it is necessary, so the more probable solution is to use std::runtime_error or std::logic_error (or a class derived from one of them).
Whether std::logic_error or std::runtime_error is more appropriate is not very clear-cut; in this case I'd probably go with std::runtime_error because the error does not seem even theoretically predictable, but given that std::domain_error and std::future_error derive from std::logic_error, it would not be entirely out of place in that hierarchy. This is, I think, a matter of opinion.
Related
I try to use boost exceptions and fall.
There are the problem code:
struct exception_base : virtual std::exception, virtual boost::exception
{
exception_base(std::exception&& e)
: std::exception(e)
{}
};
int main()
{
std::string exception_description;
try
{
BOOST_THROW_EXCEPTION(exception_base(std::runtime_error("hello exception")));
}
catch (exception_base& ex)
{
exception_description = boost::diagnostic_information(ex);
}
return 0;
}
In this case the value of the exception_description have the last string - "std::exception::what: Unknown exception". It is unexpected value. If I change BOOST_THROW_EXCEPTION to usual throw - the last string of exception_description value looks expected - "std::exception::what: hello exception"
So how to use BOOST_THROW_EXCEPTION correctly?
Your custom exception class is not necessary, and is the root cause of your problems. If you remove it you can just do this:
BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));
Then:
catch (const std::exception& ex)
And the code will work the way you expect.
Why was it not working before? Well, your exception_base class has no storage for the error message, so when you construct it from a std::exception it cannot store the message (e.g. from the original runtime_error).
You could fix it a lot of different ways, but ultimately they will boil down to the same thing: if you want your custom exception class to contain a message string, it must somehow contain that message string.
I'm a fan of not defining custom exception types 95% of the time, so I'd advise you to just keep it simple and use runtime_error (and/or logic_error).
Note that BOOST_THROW_EXCEPTION automatically adds boost::exception as a base class for the thrown type, so you do not need to do that yourself anyway--there's no advantage.
other things:
at your catch site use std::cerr << boost::diagnostic_information(ex) << std::endl; and that will print all the metadata that BOOST_THROW_EXCEPTION adds on like: file, line, function, etc
if you are throwing a std::exception inside of the BOOST_THROW_EXCEPTION() you can wrap your std::exception with boost::enable_error_info() to change the type to boost::exception and that allows you to enrich the exception with other arbitrary fields via operator<<
I have read answers to following questions ->
c++ exception : throwing std::string
c++ Exception Class Design
My requirement is to catch exceptions and allow a mechanism to reformat the error messages and then re-throw the exceptions.
So I thought of writing my exception class which will provide a method to reformat the error message at various catch points.To make reformatting easy, I'm embedding a string object in myexception_base class.
I have also referred to this article -> http://www.boost.org/community/error_handling.html which clearly says not to embed string objects in exception classes.
The article also has a quote "Peter Dimov makes an excellent argument that the proper use of a what() string is to serve as a key into a table of error message formatters." but it does not elaborate on it any further.
I have written the code as given below and my questions are -
1) If I don't embed a string object in my exception class, it will make it difficult to reformat the what messages. Please tell me How shall I approach to my requirement without embedding a string object in my exception class?
2) If I carry on with my current approach of embedding a string object and providing a method to format error message. Is my way of handling some scenarios correct ? (Issue 1 and Issue 2 in which error msg doesn't get formatted)
Issue 1 - wrong exception getting propagated to catch points ?
Issue 2 - Error Message not getting formatted in some scenarios ?
Issue 1 and Issue 2 are mentioned in comments in code below.
Kindly have a look at the code. I have given lot of comments in code so lines of code has increased but if I remove the comments it has very less lines of code.
#include <string>
#include <exception>
#include <iostream>
using namespace std;
class myexception_base : public exception {
private:
string error_msg;
public:
myexception_base(const char* str) : error_msg(str) {
// std::string here here can throw an exception while error_msg
//initialisation through MIL.
// myexception_base object will not be constructed
// and wrong exception will be propagated to catch point(Issue 1)
}
const char* what() const throw() {
try {
return error_msg.c_str();
} catch (...) {}
// c_str can throw.
// I can't remove throw specification from what()
// because what() in base std::exception has throw() specification
// In case c_str() throws an exception program will terminate
// So to stop abnormal termination of program c_str
// is wrapped in a try catch block to ignore std::string exception
// program will not terminate but what message is not reformatted
// in such scenario (Issue 2)
}
void append_error_msg(const char* str) {
error_msg.append(str);
// append can throw
// Again error_msg will not be formatted (Issue 2)
}
~myexception_base() throw() {
}
};
void f();
void f2();
void f() {
throw myexception_base("Error Msg1");
}
void f2() {
//Some intermediate Catch point will reformat e.what() msg
//by appending an error msg2
try {
f();
}
catch (myexception_base& e) {
e.append_error_msg(": Error Msg2");
throw;
}
}
int main () {
try {
f2();
}
catch(const exception& e) {
// Finally the exception is caught in the upper most layer
// and proper error_msg is given to user
cout<<e.what()<<"\n";
}
}
According to the boost documentation embedding classes which might throw during their lifetime are not an excellent candidate to be used in the exception handler mechanism, so I would like to suggest that you will simply use the good old C way of handling strings. It will require some extra effort to bring it up and running but with them you have eliminated one source of error.
So, basically there are two approaches:
In the myexception_base you declare the error_msg as being an array of N chars. In the append_error_msg you carefully check that the length of the NEW string (after the append) is not greater than N and if it is not, then you use strcat or one of the other C string handling methods. This approach might be good, since it does not allow memory leaks through the exception handling mechanism, however you can have only a limited length of error message.
In the myexception_base you declare the error_msg as being a char* (a char pointer). In the constructor you callocmemory for it (do not use new since new might throw) and in the append_error_message you realloc the pointer to be the new size (ie. old size + string to be appended.size + 1 for the 0) and then memcpy to the requested position (ie. at the position of the end of the old string in the newly allocated string). Of course, do not forget to check all the allocations/re-allocations that they have returned a valid value otherwise you might get funny behavior. And last, but not least, to avoid the classical memory leaks, free the memory of the char* in the destructor.
Good luck!
I can do this, no problem:
long lngval = 3L;
int i = lngval;
but if I try this:
try {
throw 3L;
}
catch(int i) {
cout << "caught " << i << endl;
}
I get an unhandled exception.
This seems inconsistent. what is the reason for no type conversion in this case?
In the first case, the compiler can tell exactly what you want to do: convert a long to an int. In the second case, the compiler has to assume that you might have a construct like this:
try {
try {
throw 3L;
}
catch (int i) { /* P */ }
}
catch (long l) { /* Q */ }
The idea is that the compiler can never know whether there might be a catch (long l) lurking outside the current context, so it's never safe to just pick the first possible conversion.
This is also why it's common to use a class hierarchy when throwing exceptions rather than random types like int or long: it makes it easy to add more or less specification to your exception handlers in such a way that the compiler can be sure of your intentions (via the is-a relationship).
catch does not necessarily need the exact type.
It is common and good practice to use exceptions derived from std::exception (found in <stdexcept>). The reason is that you can then catch polymorphically, i.e. you do not need to know the exact type (see also Difference: std::runtime_error vs std::exception()) and that we have a convention to handle this.
Either you use one of the ones provided by the standard (e.g. std::range_error), or if nothing suits your problems [enough], specialize std::exception:
#include <stdexcept>
class moores_law_stopped : public std::exception {
public:
virtual ~moores_law_stopped() throw() {}
virtual const char *what() const throw() {
return "moores law stopped. duck under your table.";
}
};
#include <iostream>
int main () {
try {
throw moores_law_stopped();
} catch (std::exception const &e) {
std::cerr << "oh oh: " << e.what() << std::endl;
}
}
Output:
oh oh: moores law stopped. duck under your table.
The convention is to catch by reference or const reference, so that you get polymorphic behavior without fearing object slicing.
The catch statement catches an object (or a scalar variable in your cases) given its type, so if the type mismatch, it passes to the next catch statement (if there is one) or to the default exception receiver.
In your case, you could have a second catch statement catching long, and maybe somewhere else, so your catch statement won't catch anything.
To catch any exception, just use catch() {} :)
A single tip, better use exception class, or subclass it for you own need :)
You can also throw 3; - no problem.
int and long are different types. It's an advantage of the exception handling that you can tell the exceptions apart from looking at their type (one central try block can handle exceptions of various kinds from various places / a try block can handle just some kinds of exceptions, letting others propagate).
Also, it is recommended to throw one of the standard exceptions or derive a class from one of those. Then you could just catch (const std::exception&) if you just want to handle the exception and don't care about the particular type.
You can catch multiple types in one try-catch block. In order for the compiler to know which catch block to throw to, it must be able to match the exact type. Or it can have a default catch block -- catch (...) {}, but you won't be able to get at the value thrown in that case.
I'm convinced at this point that I should be creating subclasses of std::exception for all my exception throwing needs. Now I'm looking at how to override the what method.
The situation that I'm facing, it would be really handy if the string what returns be dynamic. Some pieces of code parse an XML file for example, and adding a position or line number to the error message is useful to me.
I am trying to follow the Boost Exception handling guidelines.
What I'd like to know:
what returns a const char *, which implies any catcher is likely not going to free the string. So I need some other place to store the result, but where would that be? (I need thread-safety.)
what also includes throw() in its signature. While I can prevent my what from throwing anything, it seems to me that this method really isn't intended for anything too dynamic. If what is not the right place, then where should I be doing this instead?
From the answers I've gotten so far, it looks like the only way to accomplish this is by storing the string in the exception. The Boost guidelines recommend against this, which is confusing to me, because std::runtime_error does just that.
Even if I were to use a C-string, I'd have to use a statically sized buffer, or do memory management which can fail too. (I'm wondering if this is actually the only thing that can go wrong in std::string's copy-constructor. That would mean I won't gain anything using dynamically allocated C-strings.)
Is there any other option left?
My exception classes generally don't have anything but the constructor and look along these lines:
class MyEx: public std::runtime_error
{
public:
MyEx(const std::string& msg, int line):
std::runtime_error(msg + " on line " + boost::lexical_cast<string>(line))
{}
};
An arbitrary example, but it is the base class that handles managing the what() message.
But if you want to, you can also only assign the base part of the exception object, after you've put together the message in the constructor body.
#include <stdexcept>
#include <string>
#include <sstream>
class MyEx: public std::runtime_error
{
public:
MyEx(const std::string& msg, int line):
std::runtime_error("")
{
std::stringstream ss;
ss << msg << " on line " << line;
static_cast<std::runtime_error&>(*this) = std::runtime_error(ss.str());
}
};
#include <iostream>
int main()
{
try {
throw MyEx("Evil code", __LINE__);
}
catch (const std::exception& e) {
std::cout << e.what() << '\n';
}
}
However, regarding the boost's guidelines, perhaps you should pay attention to the point that numeric data (positions and lines) might best be made available as numbers through other methods. The guidelines say to worry less about the what() message.
Boost's guidelines appear to be based on two assumptions: copying the exception object might throw another exception, and the what() string isn't a robust or reliable tool. These are valid concerns if you're writing a library that will see wide use in a variety of environments. If you have better knowledge of how the exception will be used, you can judge if these concerns are justified or much ado about nothing. Programming is all about a series of tradeoffs, and the tradeoffs that make sense for the Boost developers might not apply to you.
Well, no problem, you can simply implement the constructor of your derived exception class to format the string you'll return from what(). Free the buffer you use for that in the destructor.
I'm accepting UncleBens' answer, because I consider it technically the most correct and complete answer to my original question.
For reference, I actually picked a different solution, and stopped using what altogether. I've refactored the code I have now to use something like this as the base exception class:
struct Exception : public virtual std::exception
{
virtual const char* what() const throw()
{
try {
return typeid(this).name();
}
catch (const std::exception& e) {
return "<unknown exception>";
}
}
// Extended description; may throw.
virtual void describe(std::ostream& out) const = 0;
};
Basically just filling what with the most meaningful thing I could find without bothering with it anywhere else. I'm going to see how this fares, I guess.
I have a C++ class and I am trying to run it in Ubuntu:
#ifndef WRONGPARAMETEREXCEPTION_H_
#define WRONGPARAMETEREXCEPTION_H_
#include <iostream>
#include <exception>
#include <string>
using namespace std;
#pragma once
class WrongParameterException: public exception
{
public:
WrongParameterException(char* message): exception(message) {};
virtual ~WrongParameterException() throw() {};
};
#endif
when I try to compile it, the compiler gives me this error:
WrongParameterException.h: In constructor ‘WrongParameterException::WrongParameterException(char*)’:
WrongParameterException.h:14: error: no matching function for call to ‘std::exception::exception(char*&)’
/usr/include/c++/4.3/exception:59: note: candidates are: std::exception::exception()
/usr/include/c++/4.3/exception:57: note: std::exception::exception(const std::exception&)
Can anyone tell me what am I doing wrong? I tried changing the message variable to string or const string or const string& but it didn't help.
Here is how I use the new exception that I created from main:
try
{
if ((strToInt1 == -1) || (parameters[1] == NULL) || (strToInt3 == -1) || (parameters[3] != NULL))
{
throw WrongParameterException("Error in the config or commands file");
}
}
catch(WrongParameterException e)
{
log.addMsg(e.what());
}
First, #pragma once is the wrong way to go about it, learn about header include guards. Related question on SO explains why using #pragma once is the wrong way to go about it. Wikipedia explains how to use include guards which serve the same purpose without any of the downsides.
Second, you are calling the constructor of std::exception with a parameter it does not know, in this case a pointer to a character array.
#include <stdexcept>
#include <string>
class WrongParameterException : public std::runtime_error {
public:
WrongParameterException(const std::string& message)
: std::runtime_error(message) { };
};
Would probably be what you want. For more information on exceptions, check out C++ FAQ Lite article on Exceptions and the exceptions article at cplusplus.com.
Good luck!
std::exception does not have a constructor that takes any kind of string, only a virtual what() method that returns the exception description.
You will have to store the string yourself and return it from there.
My advice would be:
Inherit from std::runtime_error. As advised by X-Istence above. It is conceptually a runtime error, and also the std::runtime_error constructor accepts a std::string as argument describing what happened.
About your catching the exception. I'd use catch(WrongParameterException const& e)
(note the const reference) instead of catch(WrongParameterException e), because first, the exception is normally constant in your case, and, also, using the reference, you catch any subclass of WrongParameterException in case your code evolves with some more refined exception handling.
std::exception's constructor doesn't take a string argument. You're trying to give it one, which is what causes the compile error.
You need to store your string, which would be better to handle as a std::string rather than a raw pointer, and return it from the what() method.
Looking at the declaration of the exception class in MS VS2K5, the constructor you want is:
exception (const char *const&);
so try changing your constructor to:
WrongParameterException (const char *const message)
and see if that helps. Otherwise, store the pointer in your own class and implement all the relevant methods.
A simple solution is to design your exception diferently. Here is a simple example:
class MyException : public Exception
{
public:
MyException(CString strError) { m_strError = strError; }
CString m_strError;
};
Then you can simply use your exception message as you please. This is because Exception does not have a contructor that excepts a String, so you have to stlre it on your own.