web-dev-qa-db-fra.com

Quelle est la valeur de __cplusplus pour C ++ 17?

Nous essayons de tester du code sous C++ 17 et son changer en std::uncaught_exception . Je n'arrive pas à obtenir GCC pour fournir la valeur de __cplusplus:

$ /opt/local/bin/g++ -std=c++17 -dM -E - </dev/null | grep __cplusplus
cc1: warning: command line option '-std=c++1z' is valid for C++/ObjC++ but not for C
$

Et:

$ /opt/local/bin/g++ --version
g++-mp-6 (MacPorts gcc6 6.1.0_0) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.

Quelle est la valeur de __cplusplus lors de l'utilisation de C++ 17?

27
jww

Quelle est la valeur de __cplusplus lors de l'utilisation de C++ 17?

Selon le projet de norme N4594 §16.8/p1 Noms de macro prédéfinis [cpp.predefined] ( Mine d'accentuation ):

Les noms de macro suivants doivent être définis par l'implémentation: __cplusplus Le nom __cplusplus est défini sur la valeur 201402L lors de la compilation d'une unité de traduction C++.156

156) Il est prévu que les futures versions de cette norme remplaceront la valeur de cette macro par une valeur supérieure. Les compilateurs non conformes doivent utiliser une valeur avec au plus cinq chiffres décimaux.

Cependant, la même valeur est désignée pour la norme C++ 14. Apparemment, il semble que ce ne soit pas officiel/standard __cplusplus valeur encore définie pour la norme C++ 17.

Dans les versions GCC 6.1 et 7.0, la valeur est modifiée en 201500

Démo en direct

Dans les versions 3.8 et 3.9 de Clang, la valeur est inchangée 201406 .

Par conséquent, vous devrez attendre un peu pour que la valeur standard sorte.

--- Mise à jour ---

Selon la norme C++ §19.8/p1 Noms de macro prédéfinis [cpp.predefined] ( Mine d'accentuation ):

1 Les noms de macro suivants doivent être définis par l'implémentation:

__cplusplus Le littéral entier 201703L .

Ainsi, la valeur de __cplusplus lors de l'utilisation de C++ 17 doit être 201703L .

34
101010

Je voudrais essayer

#if __cplusplus > 201402L
  // C__17 code here
  ...
#endif

En d'autres termes, les tests supérieurs à C++ 14 devraient fonctionner car les compilateurs ajoutent plus de fonctionnalités. Comme quelqu'un l'a mentionné ci-dessus, gcc utilise 201500L. Il semble que clang utilise 201406L (quatre mois après C++ 14, je suppose).

L'utilisation de ce qui précède devrait être multiplateforme et fonctionnera même lorsque C++ 17 sortira avec une vraie valeur pour __cplusplus. Pour plus de détails sur l'évolution des fonctionnalités, essayez les macros de test de fonctionnalités .

13
emsr

Je réalise que vous avez posé cette question en citant le compilateur Gnu C++ comme celui que vous utilisez, mais vous voudrez peut-être avoir une idée de ce qui se passe sur le compilateur Visual C++, et à proprement parler, votre question ne portait pas sur un compilateur spécifique .

Actuellement, à la date de cette publication, le compilateur VC++ 2017 définit __cplusplus à 199711L plutôt que ce à quoi vous pourriez vous attendre si vous définissez le compilateur pour utiliser c ++ 17.

Pour obtenir un rapport correct, vous devez également définir /Zc:__cplusplus.

(source: https://docs.Microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017 )

Pourquoi? Eh bien ... dans leurs mots:

Nous avons essayé de mettre à jour la macro par défaut et nous avons découvert que beaucoup de code ne se compilait pas correctement lorsque nous modifiions la valeur de __cplusplus.

(source: https://devblogs.Microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ )

4
Joseph Van Riper

Je ne sais pas vraiment pourquoi __cplusplus n'apparaît pas comme une macro régulière, mais je suppose que c'est pour que vous ne puissiez pas la redéfinir. C'est ainsi que je détermine sa valeur.

#include <iostream>
int main( int argc, char** argv )
{
  std::cout << __cplusplus << std::endl;
  return 0;
}

La compilation affiche ensuite la valeur.

$ g++-6 test.cpp && ./a.out
201402
$ g++-6 -std=c++17 test.cpp && ./a.out
201500

Je vérifierais si c'est >= 201500 par opposition à la vérification d'une valeur spécifique.

3
robert