Comment déterminer la version du standard C ++ utilisée par le compilateur?
115
Comment déterminez-vous quelle version du standard C ++ est implémentée par votre compilateur? Pour autant que je sache, voici les normes que j'ai connues:
Vous avez marqué ce c ++ , mais deux des trois normes que vous avez répertoriées ne sont pas des normes C ++. Quelle (s) langue (s) vous intéresse (s)?
@Mat: Posée et fermée parce que la question était insensée et contenait d'autres absurdités arbitraires. Je l'ai republié sous une forme décente. Je serais heureux de fermer celui-ci s'il semble que l'original sera réparé et rétabli, mais je ne retiens pas mon souffle.
Courses de légèreté en orbite
1
@Mat: Eh bien, la meilleure réponse n'est pas une liste statique de compilateurs, mais un moyen de déterminer par vous-même ce qui est utilisé. Alors voilà.
Courses de légèreté en orbite
1
@Als: Ce sera bientôt. Je promets. En outre, la c++-faqbalise n'a pas de pré-requis réel "nombre de fois demandé" que vous devez passer; il s'agit plus du format et de la généralité de la chose.
Courses de légèreté en orbite
Réponses:
13
À ma connaissance, il n'y a pas de moyen global de le faire. Si vous regardez les en-têtes des bibliothèques supportant plusieurs plates-formes / compilateurs multiples, vous trouverez toujours de nombreux définitions qui utilisent des constructions spécifiques au compilateur pour déterminer ces choses:
/*Define Microsoft Visual C++ .NET (32-bit) compiler */#if (defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER >= 1300)...#endif/*Define Borland 5.0 C++ (16-bit) compiler */#if defined(__BORLANDC__) && !defined(__WIN32__)...#endif
Vous devrez probablement faire de telles définitions vous-même pour tous les compilateurs que vous utilisez.
En C ++ 0x, la macro __cplusplussera définie sur une valeur différente de (supérieure à) la valeur actuelle 199711L.
Bien que ce ne soit pas aussi utile qu'on le souhaiterait. gcc(apparemment pendant près de 10 ans) avait cette valeur fixée à 1, excluant un compilateur majeur, jusqu'à ce qu'elle soit corrigée lorsque gcc 4.7.0 est sorti .
Voici les normes C ++ et la valeur à laquelle vous devriez pouvoir vous attendre __cplusplus:
C ++ pré-C ++ 98: __cplusplusest 1.
C ++ 98: __cplusplusest 199711L.
C ++ 98 + TR1: Cela se lit comme C ++ 98 et il n'y a aucun moyen de vérifier que je sache.
C ++ 11: __cplusplusest 201103L.
C ++ 14: __cplusplusest 201402L.
C ++ 17: __cplusplusest 201703L.
Si le compilateur est plus ancien gcc, nous devons recourir au piratage spécifique au compilateur (regardez une macro de version, comparez-la à une table avec des fonctionnalités implémentées) ou utilisez Boost.Config (qui fournit des macros pertinentes ). L'avantage de ceci est que nous pouvons en fait choisir des fonctionnalités spécifiques de la nouvelle norme et écrire une solution de contournement si la fonctionnalité est manquante. Ceci est souvent préféré à une solution de gros, car certains compilateurs prétendront implémenter C ++ 11, mais n'offriront qu'un sous-ensemble des fonctionnalités.
Malheureusement, une vérification plus fine des fonctionnalités (par exemple des fonctions de bibliothèque individuelles telles que std::copy_if) ne peut être effectuée que dans le système de construction de votre application (exécuter le code avec la fonctionnalité, vérifier si elle a compilé et produit des résultats corrects - autoconfest l'outil de choix si vous prenez cette route).
Il ne semble pas que les fournisseurs de compilateurs mettent à jour cela - peut-être qu'ils attendent d'être pleinement conformes à la norme? ( Stackoverflow.com/q/14131454/11698 )
Richard Corden
2
@prnr: C'est peut-être vrai, mais c'est à l'utilisateur qui a posé la question de décider quelle réponse accepter. Au moment où la réponse qui est actuellement marquée comme acceptée a été publiée, elle était correcte, donc l'affiche originale l'a acceptée. Cet utilisateur peut décider de modifier la réponse acceptée, mais il se peut qu'il ne soit plus actif sur le site. Voir: meta.stackexchange.com/questions/120568/…
Dan Korn
3
vs2017 donne la valeur de __cplusplus 199711
Al Mamun
5
@AlMamun Microsoft partiellement corrigé __cplusplusuniquement dans VS 15.7. Voir leur blog de l'équipe Visual C ++
Ivan_Bereziuk
1
Le lien vers la FAQ est rompu.
brainplot
38
Veuillez exécuter le code suivant pour vérifier la version.
C'est drôle, car sur les studios visuels, la valeur de __cplusplus est 199711L et le code que vous avez posté a renvoyé c ++ 98 cependant, j'ai utilisé des fonctionnalités de c ++ 14, y compris des modèles de variables et decltype (auto). Est-il possible que la mauvaise version de la macro ait été implémentée?
@DaanTimmer Je suis confus par cet article, il semble supposer que vous savez comment utiliser le /Zc:__cplusplusdrapeau. Je ne peux pas simplement std::cout << /Zc:__cplusplus;parce que les deux-points et les barres obliques ne peuvent pas faire partie des noms de variables bien sûr. Êtes-vous en mesure d'expliquer comment procéder? Merci.
En fonction de ce que vous souhaitez réaliser, Boost.Config peut vous aider. Il ne fournit pas de détection de la version standard, mais il fournit des macros qui vous permettent de vérifier la prise en charge de certains langages / fonctionnalités du compilateur.
La vérification des fonctionnalités est probablement une meilleure idée que la vérification des versions standard, de toute façon. Peu de compilateurs prennent en charge tout à partir d'une norme, mais s'ils prennent tous en charge le nombre limité de fonctionnalités dont vous avez besoin, peu importe si les autres fonctionnalités d'une norme donnée sont implémentées et fonctionnent correctement.
Rob Kennedy
4
__cplusplus
Dans C ++ 0x, la macro __cplusplus sera définie sur une valeur différente de (supérieure à) la valeur 199711L actuelle.
Utilisez __cpluspluscomme suggéré. Une seule note pour le compilateur Microsoft, utilisezZc:__cplusplus commutateur du compilateur pour activer__cplusplus
Le __STDC__fait de savoir si est défini et sa valeur sont définis par l'implémentation en C ++.
Rob Kennedy
@Rob: Oui, ça l'est. @Tor: J'ai essayé dans VC ++ 2005 mais cela dit que STDC est un identifiant non déclaré. Il est cependant répertorié comme l'une de ces macros prédéfinies. Cependant, STDC_VERSION n'existe pas.
jasonline
Cela vous indique la version du langage de programmation C pris en charge par le compilateur. Il ne vous dit rien sur la version du langage C ++ qui est prise en charge.
Dan Moulding
0
Normalement, vous devez utiliser __cplusplusdefine pour détecter C ++ 17, mais par défaut le compilateur Microsoft ne définit pas correctement cette macro, voir https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - vous avez besoin pour modifier les paramètres du projet pour inclure le /Zc:__cpluspluscommutateur, ou vous pouvez utiliser une syntaxe comme celle-ci:
c++-faq
balise n'a pas de pré-requis réel "nombre de fois demandé" que vous devez passer; il s'agit plus du format et de la généralité de la chose.Réponses:
À ma connaissance, il n'y a pas de moyen global de le faire. Si vous regardez les en-têtes des bibliothèques supportant plusieurs plates-formes / compilateurs multiples, vous trouverez toujours de nombreux définitions qui utilisent des constructions spécifiques au compilateur pour déterminer ces choses:
Vous devrez probablement faire de telles définitions vous-même pour tous les compilateurs que vous utilisez.
la source
À partir de la FAQ Bjarne Stroustrup C ++ 0x :
Bien que ce ne soit pas aussi utile qu'on le souhaiterait.
gcc
(apparemment pendant près de 10 ans) avait cette valeur fixée à1
, excluant un compilateur majeur, jusqu'à ce qu'elle soit corrigée lorsque gcc 4.7.0 est sorti .Voici les normes C ++ et la valeur à laquelle vous devriez pouvoir vous attendre
__cplusplus
:__cplusplus
est1
.__cplusplus
est199711L
.__cplusplus
est201103L
.__cplusplus
est201402L
.__cplusplus
est201703L
.Si le compilateur est plus ancien
gcc
, nous devons recourir au piratage spécifique au compilateur (regardez une macro de version, comparez-la à une table avec des fonctionnalités implémentées) ou utilisez Boost.Config (qui fournit des macros pertinentes ). L'avantage de ceci est que nous pouvons en fait choisir des fonctionnalités spécifiques de la nouvelle norme et écrire une solution de contournement si la fonctionnalité est manquante. Ceci est souvent préféré à une solution de gros, car certains compilateurs prétendront implémenter C ++ 11, mais n'offriront qu'un sous-ensemble des fonctionnalités.Le Wiki Stdcxx héberge une matrice complète pour la prise en charge par le compilateur des fonctionnalités C ++ 0x (si vous osez vérifier les fonctionnalités vous-même).
Malheureusement, une vérification plus fine des fonctionnalités (par exemple des fonctions de bibliothèque individuelles telles que
std::copy_if
) ne peut être effectuée que dans le système de construction de votre application (exécuter le code avec la fonctionnalité, vérifier si elle a compilé et produit des résultats corrects -autoconf
est l'outil de choix si vous prenez cette route).la source
__cplusplus
uniquement dans VS 15.7. Voir leur blog de l'équipe Visual C ++Veuillez exécuter le code suivant pour vérifier la version.
la source
/Zc:__cplusplus
)/Zc:__cplusplus
drapeau. Je ne peux pas simplementstd::cout << /Zc:__cplusplus;
parce que les deux-points et les barres obliques ne peuvent pas faire partie des noms de variables bien sûr. Êtes-vous en mesure d'expliquer comment procéder? Merci.En fonction de ce que vous souhaitez réaliser, Boost.Config peut vous aider. Il ne fournit pas de détection de la version standard, mais il fournit des macros qui vous permettent de vérifier la prise en charge de certains langages / fonctionnalités du compilateur.
la source
FAQ C ++ 0x par BS
la source
Utilisez
__cplusplus
comme suggéré. Une seule note pour le compilateur Microsoft, utilisezZc:__cplusplus
commutateur du compilateur pour activer__cplusplus
Source https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
la source
Après un rapide google :
__STDC__
et__STDC_VERSION__
, voir icila source
__STDC__
fait de savoir si est défini et sa valeur sont définis par l'implémentation en C ++.Normalement, vous devez utiliser
__cplusplus
define pour détecter C ++ 17, mais par défaut le compilateur Microsoft ne définit pas correctement cette macro, voir https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - vous avez besoin pour modifier les paramètres du projet pour inclure le/Zc:__cplusplus
commutateur, ou vous pouvez utiliser une syntaxe comme celle-ci:la source