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 ?
Best Solution
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:std::exception
The first case is straightforward; just use
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 eitherstd::logic_error
orstd::runtime_error
, which inheritstd::exception
and do have constructors taking a string argument, somight already solve the problem.
catch
clauses that caught thestd::exception
will also catch thestd::runtime_error
. There is one potential problem, though:catch
clauses that catchstd::runtime_error
would not have caught thestd::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 catchesstd::runtime_error
but should not catch the exception thrown by this code, you could derive your own exception class fromstd::exception
that does take a string argument. Because the class is new, it will not be caught by existingcatch
clauses. For example:And then
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
orstd::logic_error
(or a class derived from one of them).Whether
std::logic_error
orstd::runtime_error
is more appropriate is not very clear-cut; in this case I'd probably go withstd::runtime_error
because the error does not seem even theoretically predictable, but given thatstd::domain_error
andstd::future_error
derive fromstd::logic_error
, it would not be entirely out of place in that hierarchy. This is, I think, a matter of opinion.