I'm trying to create a custom exception that derives from std::exception
and overrides what()
. At first, I wrote it like this:
class UserException : public std::exception
{
private:
const std::string message;
public:
UserException(const std::string &message)
: message(message)
{}
virtual const char* what() const override
{
return message.c_str();
}
};
This works fine in VS2012, but it doesn't compile in GCC 4.8 with -std=c++11
:
error: looser throw specifier for ‘virtual const char* UserException::what() const’
So I add noexcept
:
virtual const char* what() const noexcept override
This works fine in GCC, but it doesn't compile in Visual Studio (because VS 2012 doesn't support noexcept
):
error C3646: 'noexcept' : unknown override specifier
What is the recommended way to deal with this? I want the same code to compile with both compilers and I'm using C++11 features, so I can't compile with different -std
.
Use a macro
#ifndef _MSC_VER
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif
And then define the function as
virtual const char* what() const NOEXCEPT override
You could also modify that to allow noexcept
on later versions of VS by checking the value of _MSC_VER
; for VS2012 the value is 1600.
"noexcept" is only supported since the Visual Studio 2015 (as stated here: https://msdn.microsoft.com/en-us/library/wfa0edys.aspx). I have used following code with Visual Studio 2013 (derived from above examples):
#if !defined(HAS_NOEXCEPT)
#if defined(__clang__)
#if __has_feature(cxx_noexcept)
#define HAS_NOEXCEPT
#endif
#else
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026
#define HAS_NOEXCEPT
#endif
#endif
#ifdef HAS_NOEXCEPT
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif
This check works to see if noexcept
is supported:
// Is noexcept supported?
#if defined(__clang__) && __has_feature(cxx_noexcept) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 180021114
# define NOEXCEPT noexcept
#else
# define NOEXCEPT
#endif
The above works with Clang, GCC and MSVC.
use BOOST_NOEXCEPT
in <boost/config.hpp>
The boost config library was designed for compatibility issues like this. According to the doc:
If
BOOST_NO_CXX11_NOEXCEPT
is defined (i.e. C++03 compliant compilers) these macros are defined as:#define BOOST_NOEXCEPT #define BOOST_NOEXCEPT_OR_NOTHROW throw() #define BOOST_NOEXCEPT_IF(Predicate) #define BOOST_NOEXCEPT_EXPR(Expression) false
If
BOOST_NO_CXX11_NOEXCEPT
is not defined (i.e. C++11 compliant compilers) they are defined as:#define BOOST_NOEXCEPT noexcept #define BOOST_NOEXCEPT_OR_NOTHROW noexcept #define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) #define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression))
Many of the other answers here have a similar implementation but this library is cleaner, better tested, and will do the right thing when your compiler is upgraded. I recommend looking at the boost config library in general for other features, especially in this time of language flux and varying levels of support among compilers.
Add the following lines in your code in Visual Studio:
#ifdef _NOEXCEPT
#define noexcept _NOEXCEPT
#endif
The noexcept is one of the easiest "lacks" of MSVC to deal with: Just use the macro _NOEXCEPT
which under MSVC2013 is defined in yvals.h .
What I've recently used is following:
#ifdef _MSC_VER
#define NOEXCEPT _NOEXCEPT
#else
#define NOEXCEPT noexcept
#endif
and then just use NOEXCEPT
everywhere.
It seems that the old throw()
(deprecated in C++11) works in both compilers. So I changed the code to:
virtual const char* what() const throw() override
The other way to go around is create header file and include it if necessary in your source code that should be compile by gcc, vc,or clang.
no_except_work_around.h
#ifndef no_except_work_around_H
#define no_except_work_around_H
#if (_MSC_VER <= 1800)
#include <xkeycheck.h>
#define noexcept
#endif
#endif //no_except_work_around_H
=====================================================
P.S> doesn't cover case noexcept(false) but works fine for VC2010,2012,2013, gcc 4.9
#IF
s may work, even if a bit hacky.
You could just do this:
#if __GNUG__
virtual const char* what() const noexcept override
#else
virtual const char* what() const override
#endif
//method body
add the below path to the additional include directories
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include
at this location there is file called "yvals.h" which contain definition of _NOEXCEPT
来源:https://stackoverflow.com/questions/18387640/how-to-deal-with-noexcept-in-visual-studio