web-dev-qa-db-ja.com

c ++ 1z動的例外指定エラー

新しいGCCバージョン7.2.1でプロジェクトをコンパイルしようとしていますが、動的例外仕様に問題があります。

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

問題は、これらのエラーが、私が管理していないサードパーティのライブラリにあることです。

それを修正する方法はありますか?私の知る限り、エラーを警告に置き換えるようコンパイラーに指示することはできません。 C++ 1zの新機能を使用したいので、--std=c++14を使用することはできません。

13

C++ 17は、 P00 の結果として、動的例外指定を削除しました。それ以前は、C++ 11以降は非推奨でした。それらはもはや言語の一部ではないので、それを修正する方法は実際にはありません。そのサードパーティのライブラリが必要である限り、それが変更されるまでは、C++ 14のままです。


あなたが絶望的なら、あなたは試すことができます:

#define throw(...)

しかし、私はそれをお勧めしません。

8
Barry

さて、私は少しの回避策を書きました。

#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を使用している場合、アロケーターでのスローは許可されなくなりました。ライブラリのヘッダーをよく見ると、ライブラリ内のデフォルトのアロケータの定義を含むマクロが定義されていることがわかります。悲しいことに、すでに定義されている可能性があることを無視してそこで定義されるため、オーバーライドできません。したがって、どういうわけか、とにかくトローをオーバーライドする必要があります。

基本的なトリックは、マクロでtrow関数をオーバーライドすることです。これを行うと、ライブラリ内のすべてのincludeのtrow演算子もオーバーライドするという問題が発生しますが、これは適切な解決策ではありません(また、機能しません)。ご存知かもしれませんが、ヘッダーを含めている場合、ヘッダーは1回だけ含まれます(主にヘッダーガードのおかげです)。したがって、ライブラリに含まれているヘッダーをインクルードするトリックは、ターゲットライブラリのスローインクルードヘッダーをオーバーライドするのではなく、既にインクルードしているため、実際にはヘッダーをインクルードしません。

5
WolverinDEV
  1. 上記のコメントで述べたように分離層。何かのようなもの:

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

_ void fn() throw (int) { }
_

_#endif // __cplusplus_

  1. throw(whatever)noexcept(false)で置き換え始めました。

いずれにせよ、楽しみの準備をしてください!

2
ibroheem

同じ問題に遭遇したため、/ 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>&);
1
cocheci

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を使用できるようになります。

0
user3726672