c ++ 1z动态异常规范错误

时间:2017-11-14 11:31:47

标签: c++ c++17 exception-specification gcc7

我正在尝试使用新的GCC版本7.2.1编译我的项目,并且遇到动态异常规范的问题:

error: ISO C++1z does not allow dynamic exception specifications
  MEMORY_ALLOC_OPERATORS(SQLException)

问题是这些错误来自我无法控制的第三方库。

有没有办法解决它?据我所知,我不能告诉编译器用警告替换错误。使用--std=c++14不是一种选择,因为我想使用C ++ 1z中的新功能。

5 个答案:

答案 0 :(得分:8)

由于P0003

C ++ 17删除了动态异常规范。在此之前,自C ++ 11以来,它们已被弃用。它们不再是语言的一部分,因此没有办法解决它。只要您需要第三方库,直到它发生变化,您就会陷入C ++ 14。

如果你很绝望,你可以尝试:

#define throw(...)

但我不推荐它。

答案 1 :(得分:5)

好吧,我写了一些解决方法。

#if __cplusplus >= 201703L
    /* MySQL override. This needed to be inclided before cppconn/exception.h to define them */
    #include <stdexcept>
        #include <string>
    #include <memory>

    /* Now remove the trow */
    #define throw(...)
    #include <cppconn/exception.h>
    #undef throw /* reset */
#endif

简短说明: 如果我们使用的是c ++ 17,则在分配器上不再允许throw。 如果您仔细查看该库的标头,您会看到有一个定义的宏,其中包含该库中默认分配器的定义。可悲的是,它不能被覆盖,因为它在那里被定义而忽略了已经被定义的情况。因此,无论如何,您必须以某种方式覆盖特洛伊。

一个基本技巧是使用宏重写trow函数。 这样做导致我们遇到的问题是,我们还重写了库中所有包含的trow运算符,这不是一个好的解决方案(并且也不起作用)。 如您所知,如果要包含标头,则它只会被包含一次(主要是由于标头保护)。 因此,窍门是包括库包含的标头,而不是覆盖目标库的标头,而抛出则不包含目标库的标头,因为我们已经这样做了。

答案 2 :(得分:1)

  1. 隔离层,如上面评论中提到的那样。类似的东西:
  2. fully_connected

    #if __cplusplus < 201703L // Standards below C++2017

    void fn() throw (int) { }

    1. 您已经开始用#endif // __cplusplus替换throw(whatever)了。
    2. 无论哪种方式,都要准备好开心!

答案 3 :(得分:1)

遇到同样的问题,所以我不得不在/usr/include/cppconn/exception.h中更改这个宏定义:

#define MEMORY_ALLOC_OPERATORS(Class) \
void* operator new(size_t size) noexcept(false) { return ::operator new(size); }  \
void* operator new(size_t, void*) noexcept; \
void* operator new(size_t, const std::nothrow_t&) noexcept; \
void* operator new[](size_t) noexcept(false); \
void* operator new[](size_t, void*) noexcept; \
void* operator new[](size_t, const std::nothrow_t&) noexcept; \
void* operator new(size_t N, std::allocator<Class>&);

答案 4 :(得分:0)

在MSVC中,您的throw(...)说明符始终始终是空白。就像在其中一样,Visual Studio总是默默地编译如下函数:

void SomeFunction() throw(std::string) {...} 

如果是这样的话:

void SomeFunction() {...}

或从现代C ++ 11开始:

void SomeFunction() noexcept(false) {...}

因此,对于所有跨平台3P程序包中的99%,该宏和#include骇客都集中在:

#define throw(...) 

将立即生效,因为该程序包的本机Windows版本已经在默默地执行该宏的操作。失败的话,您可以将所有对有问题的接口的调用和引用包装在您自己的几个C ++ 14源文件中。这至少会让您的项目其余部分使用c ++ 17。