web-dev-qa-db-fra.com

erreur de spécification d'exception dynamique c ++ 1z

J'essaie de compiler mon projet avec la nouvelle version 7.2.1 de GCC et rencontre un problème avec les spécifications d'exception dynamique:

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

Le problème est que ces erreurs proviennent de bibliothèques tierces que je ne contrôle pas.

Y a-t-il un moyen de le réparer? Autant que je sache, je ne peux pas dire au compilateur de remplacer les erreurs par des avertissements. Utiliser --std=c++14 n'est pas une option car je veux utiliser les nouvelles fonctionnalités de C++ 1z.

8
Pustovalov Dmitry

C++ 17 a supprimé les spécifications d'exception dynamique à la suite de P0003 . Avant cela, ils étaient obsolètes depuis C++ 11. Ils ne font plus partie du langage, il n'y a donc pas vraiment de moyen de le réparer. Tant que vous avez besoin de cette bibliothèque tierce, jusqu'à ce que cela change, vous êtes bloqué en C++ 14.


Si vous êtes désespéré, vous pouvez essayer:

#define throw(...)

mais je ne le recommanderais pas. 

7
Barry

Eh bien, j'ai écrit une petite solution de contournement.

#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

Brève explication: Si nous utilisons c ++ 17, la projection n’est plus autorisée sur les allocateurs . Si vous examinez de plus près l’en-tête de la bibliothèque, vous verrez qu’une macro est définie, qui contient les définitions de l’allocateur par défaut dans la bibliothèque. Malheureusement, il ne peut pas être remplacé car il est défini à cet endroit en ignorant qu'il est peut-être déjà défini. Donc de toute façon, vous devez quand même annuler le trow.

Un truc de base consiste à remplacer la fonction trow par une macro. Cela nous mène au problème que nous remplaçons également l'opérateur de trow pour tous les inclus dans la bibliothèque qui n'est pas une bonne solution (et ne fonctionne pas non plus) . Comme vous le savez peut-être, si vous ' Si vous incluez un en-tête, il ne sera inclus qu’une fois (la plupart du temps, grâce aux gardes de l’en-tête) . bibliothèque cible, qui n'inclut pas encore leur en-tête car nous l'avons déjà fait. 

3
WolverinDEV
  1. Couche d'isolation mentionnée dans le commentaire ci-dessus. Quelque chose comme:

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

 void fn() throw (int) { }

#endif // __cplusplus

  1. Il est grand temps de commencer à remplacer throw(whatever) par noexcept(false).

Quoi qu'il en soit, soyez prêt à vous amuser!

1
ibroheem

Courant dans le même problème, j'ai donc dû changer cette définition de macro dans /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