C++ 20 – feature test macros

Bonjour à tous ! Aujourd’hui je vous propose de nous intéresser aux nouvelles fonctions du préprocesseur pour le feature testing, qui ont été acceptées pour C++20.

La P0941 introduit certaines nouveautés dans le but de permettre de tester la présence d’une fonctionnalité du langage ou d’un élément de la bibliothèque standard sur un compilateur. Ceci vient compléter __has_include que nous avait fourni C++17.

Chaque macro de feature-testing est donc définie si le compilateur / la plateforme supporte la fonctionnalité correspondante. Dans ce cas, la valeur est un entier (pp-number) basé sur la date d’ajout de la fonctionnalité au draft du standard :

Lorsqu’une fonctionnalité donnée subit un changement significatif, la valeur est mise-à-jour ce qui permet de tester la présence d’une version particulière d’une feature :

Cette page de cppreference.com propose une liste des différentes macros de feature-testing disponibles avec C++20. La majorité des fonctionnalités introduites depuis C++11 sont associées à une macro, en voici quelques exemples :

  • C++11 : __cpp_decltype, __cpp_unicode_literals azdazd
  • C++14 : __cpp_variable_templates, __cpp_sized_deallocation
  • C++17 : __cpp_inline_variables, __cpp_enumerator_attributes
  • C++20 : __cpp_impl_three_way_comparison, cpp_nontype_template_parameter_class

De plus, C++20 voit l’ajout de la directive __has_cpp_attribute qui permet de tester la présence d’un attribut. De la même manière, la valeur renvoyée est un entier correspondant à l’année et au mois de la publication dans le working draft. Dans le cas d’un attribut non-standard, la valeur est non-nulle si l’attribut est présent, laissée au choix de l’implémentation.

Il est donc possible de tester le support d’un attribut à la compilation :

Notez par ailleurs que __has_cpp_attribute n’est utilisable que dans les directives préprocesseurs conditionnelles #if et #elif (et #ifdef, #ifndef, defined). Le code suivant n’est donc pas valide (même si clang et gcc semblent l’accepter tout de même) :

Bien entendu, cela implique qu’un compilateur ne supportant pas C++20 ne supportera pas ces macros. L’opérateur préprocesseur defined peut être utilisé pour tester en amont la présence de la macro :

C’est tout pour aujourd’hui ! Je vous dis à bientôt pour un nouvel article.

 

Références et ressources

%d bloggers like this: