web-dev-qa-db-fra.com

Existe-t-il une directive de préprocesseur pour détecter la prise en charge de C ++ 11x?

Si j'ai du code où j'aimerais utiliser autant que possible les extensions C++ 11x, mais j'ai un repli si ce n'est pas pris en charge. Actuellement, la version OSX de GCC et le compilateur VisualC ont peu ou pas de support pour C++ 11x, donc j'utilise:

#if (defined(__Apple__) || (defined(_WIN32)))
   ...fallback code without C++11x ...
#else
   ... code using C++11x ...
#endif

Et cela fonctionne, mais ce n'est pas vraiment la bonne chose à faire, d'autant plus que le compilateur gcc dans MacPorts prend en charge c ++ 11x.

Y a t-il #define C11X_SUPPORTED macro de type? Peut-être quelque chose que seul GCC possède?

49
Kenneth

__cplusplus doit être défini comme 199711L dans les compilateurs pré-C++ 11, 201103L dans ceux qui supportent C++ 11. Que cela aide beaucoup dans la pratique est une autre question: la plupart des compilateurs ne sont qu'à mi-chemin, il ne faut donc pas le définir comme 201103L, même s'ils prennent en charge les fonctionnalités qui vous intéressent. Et il n'est pas rare qu'un compilateur ment: un compilateur qui le définit comme 199711L et ne prend pas en charge export pour les modèles, par exemple. Mais il n'y a pas de test standard de fonctionnalité par fonctionnalité.

La solution la plus simple consiste simplement à ne pas utiliser de nouvelle fonctionnalité particulière jusqu'à ce que vous soyez sûr que tous les compilateurs la prennent en charge. Vous devez quand même écrire et prendre en charge le code de secours; pourquoi maintenir deux versions. La seule exception à cette règle peut être les nouvelles fonctionnalités qui ont un impact sur les performances: que le compilateur prenne en charge les sémantiques de déplacement ou non. Dans de tels cas, je suggère un fichier include dépendant du compilateur, que vous écrivez vous-même en fonction de la documentation du compilateur et des tests personnels; ce n'est pas parce que le compilateur peut documenter qu'il prend en charge une fonctionnalité spécifique que son support est exempt de bogues. Créez simplement un répertoire par compilateur ciblé, placez-y ce fichier et spécifiez le -I ou /I option dans votre fichier makefile ou projet.

Et vos tests devraient être quelque chose comme:

#ifdef HAS_MOVE_SEMANTICS
...
#endif

plutôt que sur le compilateur, la version ou autre.

52
James Kanze

Vous pouvez vérifier la valeur de __cplusplus macro. Pour C++ 11, il est supérieur à 199711L.

Donc quelque chose comme

#if __cplusplus > 199711L

#endif
26
Luchian Grigore

La bibliothèque Boost.Config fournit macros de préprocesseur granulaire que vous pouvez utiliser pour compiler conditionnellement en fonction de la présence d'une fonctionnalité C++ 11 donnée.

(Pour un compilateur, la prise en charge de C++ 11 n'a pas besoin d'être une proposition tout ou rien. Par exemple, réfléchissez à la manière dont Microsoft choisi parmi les fonctionnalités de C++ 11 à inclure dans Visual Studio 2012 en fonction de ce qu'il croyaient que ce serait le plus avantageux pour leurs clients.)

7
Edward Brey