Is there a clean way or workaround to achieve a throwing destructor compilable by both c++98
and c++1x
compilers which is cross-platform and does not produce warnings?
Given
There is a legacy class representing an error code, which throws if it is not handled. To achieve this it uses a throwing destructor.
Goal
A cross-platform (g++, VC++) implementation that compiles and works with both older c++98
compilers (thank you MS for the WindowsCE) as well as with compilers supporting c++1x
. Ideally, it should not produce any warnings.
Problem
The problem is that since c++11
all destructors are non-throwing by default (will terminate at run-time if an exception is thrown). Workaround is noexcept(false)
, but it is not available in c++98
. On the other hand c++98
has exception specifications, which are generally considered bad and are deprecated since c++11
E.g., see: Why are exception specifications bad?.
Current workaround
class ThrowingErrorCode
{
public:
...
// silence the VC exception specification warning
// we need to use exception specification for a throwing destructor, so that it would compile with both c++98 and c++11
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4290 )
#endif
~ThrowingErrorCode() throw(ErrorCodeException)
{
...
throw ErrorCodeException("Must handle error code");
}
// enable the warning again
#ifdef _MSC_VER
#pragma warning( pop )
#endif
};
I don't quite like it, as it needs to suppress warnings and uses deprecated exception specification. Could you please tell me if there a better/cleaner way of doing this?
This is my first StackOverflow question. If you have any advice on improving the question, please let me know :-)
You could define a simple macro to effect a throwing exception specification:
Usage:
Non-conforming compilers may not set the
__cplusplus
macro correctly, in which case you may need to compare against additional vendor macros. For example, some versions of MSVC++ can use this code: