Le préprocesseur prend en charge le remplacement des macros de texte. Le remplacement de macro texte de type fonction est également pris en charge.

Syntaxe

#defineidentificateurliste de remplacement(facultatif) (1)
#defineidentifiant(paramètres)liste de remplacement(facultatif) (2)
#defineidentifiant(paramètres, ... )liste de remplacement(facultatif) (3) (depuis C++11)
#defineidentifiant( ... )liste de remplacement(facultatif) (4) (depuis C++11)
#undef identifiant (5)

Explication

#define directives

Le site #define définissent les identifiant comme une macro, c'est-à-dire qu'elles demandent au compilateur de remplacer toutes les occurrences successives de identificateur par liste de remplacement qui peut éventuellement être traité de manière complémentaire. Si l'identificateur est déjà défini comme un type de macro quelconque, le programme est mal formé à moins que les définitions soient identiques.

Macros de type objet

Les macros de type objet remplacent chaque occurrence de defined identificateur par liste de remplacement. Version (1) de la #define se comporte exactement de la même manière.

Macros de type fonction

Les macros de type fonction remplacent chaque occurrence de défini identificateur par liste de remplacement en prenant en plus un certain nombre d'arguments, qui remplacent alors les occurrences correspondantes de n'importe lequel des éléments paramètres dans les liste de remplacement.

La syntaxe d'une invocation de macro de type fonction est similaire à celle d'un appel de fonction : chaque instance du nom de la macro suivie d'un ( en tant que jeton de prétraitement suivant, introduit la séquence de jetons qui est remplacée par la fonction liste de remplacement. La séquence est terminée par l'élément correspondant ) correspondant, en sautant les paires de parenthèses gauche et droite correspondantes.

Pour la version (2), le nombre d'arguments doit être le même que le nombre de paramètres dans la définition de la macro. Pour les versions (3,4), le nombre d'arguments doit être le suivant supérieur à(jusqu'à C++20)au moins autant que(depuis C++20) le nombre de paramètres (sans compter ...). Dans le cas contraire, le programme est mal formé. Si l'identificateur n'est pas en notation fonctionnelle, c'est-à-dire qu'il n'a pas de parenthèses après lui-même, il n'est pas remplacé du tout.

Version (2) de la #define définit une macro simple de type fonction.

La version (3) de la directive #define définit une macro de type fonction avec un nombre variable d'arguments. Les arguments supplémentaires (appelés arguments variables) sont accessibles en utilisant __VA_ARGS__ identifiant, qui est alors remplacé par des arguments, fournis avec l'identifiant à remplacer.

Version (4) de la #define définit une macro de type fonction avec un nombre variable d'arguments, mais sans arguments réguliers. Les arguments (appelés arguments variables) ne sont accessibles qu'avec __VA_ARGS__ identifiant, qui est alors remplacé par des arguments, fournis avec l'identifiant à remplacer.

Pour les versions (3,4), replacement-list peut contenir la séquence de jetons __VA_OPT__ (contenu)qui est remplacée par contenu si __VA_ARGS__ est non vide, et se développe en rien sinon.

#defineF(...)f(0__VA_OPT__(,) __VA_ARGS__)#defineG(X,...)f(0, X __VA_OPT__(,) __VA_ARGS__)#defineSDEF(sname,...) S sname __VA_OPT__(={ __VA_ARGS__ })F(a, b, c)// replaced by f(0, a, b, c)F()// replaced by f(0)G(a, b, c)// replaced by f(0, a, b, c)G(a,)// replaced by f(0, a)G(a)// replaced by f(0, a)SDEF(foo);// replaced by S foo;SDEF(bar,1,2);// replaced by S bar = { 1, 2 };
(depuis C++20)

Remarque : si un argument d'une macro de type fonction comprend des virgules qui ne sont pas protégées par des paires appariées de parenthèses gauche et droite (ce que l'on trouve le plus souvent dans les listes d'arguments de modèles, comme dans la section assert(std::is_same_v<int, int>); ou BOOST_FOREACH(std::pair<int,int> p, m)), la virgule est interprétée comme un séparateur d'argument de macro, ce qui entraîne un échec de compilation dû à une non-concordance du nombre d'arguments.

Noms de macro réservés

Une unité de traduction qui comprend un en-tête de bibliothèque standard ne peut pas #define ou #undef noms déclarés dans tout en-tête de bibliothèque standard.

Une unité de traduction qui utilise une partie quelconque de la bibliothèque standard ne peut pas #define ou #undef des noms lexicalement identiques à :

  • mots-clés
  • identificateurs ayant une signification particulière
  • tout jeton d'attribut standard
(depuis C++11)

sauf que

et unlikely peuvent être définis comme des macros de type fonction.

(depuis C++20)

Dans le cas contraire, le comportement est indéfini.

# et ## opérateurs

Dans les macros de type fonction, un # devant un identificateur dans le liste de remplacement soumet l'identifiant à un remplacement de paramètres et place le résultat entre guillemets, créant ainsi une chaîne de caractères littérale. En outre, le préprocesseur ajoute des barres obliques inverses pour échapper aux guillemets entourant les chaînes de caractères intégrées, le cas échéant, et double les barres obliques inverses dans la chaîne de caractères si nécessaire. Tous les espaces en tête et en queue de chaîne sont supprimés, et toute séquence d'espaces au milieu du texte (mais pas à l'intérieur des chaînes littérales imbriquées) est réduite à un seul espace. Cette opération est appelée "stringification". Si le résultat de la stringification n'est pas un littéral de chaîne valide, le comportement est indéfini.

Lorsque # apparaît avant __VA_ARGS__l'ensemble du __VA_ARGS__ étendu est placé entre guillemets :

#defineshowlist(...)puts(#__VA_ARGS__)showlist();// expands to puts("")showlist(1,"x",int);// expands to puts("1, "x", int")
(depuis C++11)

A ## entre deux identificateurs successifs quelconques dans le liste de remplacement exécute le remplacement de paramètres sur les deux identificateurs (qui ne sont pas macro-expansés en premier) et concatène ensuite le résultat. Cette opération est appelée "concaténation" ou "collage de jetons". Seuls les jetons qui forment ensemble un jeton valide peuvent être collés : les identificateurs qui forment un identificateur plus long, les chiffres qui forment un nombre ou les opérateurs. + et = qui forment un +=. Un commentaire ne peut pas être créé en collant / et * car les commentaires sont supprimés du texte avant que la substitution de macro soit prise en compte. Si le résultat de la concaténation n'est pas un token valide, le comportement est indéfini.

Note : certains compilateurs proposent une extension qui permet au ## d'apparaître après une virgule et avant __VA_ARGS__, auquel cas le ## ne fait rien lorsque les arguments de la variable sont présents, mais supprime la virgule lorsque les arguments de la variable ne sont pas présents : cela permet de définir des macros telles que... fprintf (stderr, format, ##__VA_ARGS__).

#undef directive

Le site #undef indéfinit la directive identifiant c'est-à-dire qu'elle annule la définition précédente de l'identificateur identificateur par #define directive. Si l'identifiant n'a pas de macro associée, la directive est ignorée.

Macros prédéfinies

Les noms de macro suivants sont prédéfinis dans chaque unité de traduction.

__cplusplus dénote la version de la norme C++ qui est utilisée, s'étend à la valeur 199711L.(jusqu'à C++11), 201103L (C++11), 201402L (C++14) ou 201703L (C++17)
(constante macro)
__STDC_HOSTED__(C++11) s'étend à la constante entière 1 si l'implémentation est hébergée (fonctionne sous un OS), ​0​ si elle est autonome (fonctionne sans système d'exploitation).
(constante macro)
__FILE__ se développe vers le nom du fichier actuel, comme un littéral de chaîne de caractères, peut être modifié par la directive #line.
(constante macro)
__LINE__ se développe vers le numéro de ligne du fichier source, une constante entière, peut être modifiée par la directive #line.
(constante macro)
__DATE__ étend à la date de la traduction, une chaîne de caractères littérale de la forme "Mmm dd yyyy". Le premier caractère de "dd" est un espace si le jour du mois est inférieur à 10. Le nom du mois est comme s'il était généré par std::asctime()
(constante macro)
__TIME__ étend à l'heure de la traduction, un littéral de chaîne de caractères de la forme "hh:mm:ss".
(constante macro)
__STDCPP_DEFAULT_NEW_ALIGNMENT__(C++17) s'étend à un std::size_t dont la valeur est l'alignement garanti par un appel à l'opérateur new non conscient de l'alignement (des alignements plus importants seront transmis à la surcharge consciente de l'alignement, telle que operator new(std::size_t, std::align_val_t)
(constante macro)

Les noms de macro supplémentaires suivants peuvent être prédéfinis par les implémentations.

__STDC__ valeur définie par l'implémentation, si elle est présente, généralement utilisée pour indiquer la conformité au langage C.
(constante macro)
__STDC_VERSION__(C++11) valeur définie par l'implémentation, si présente
(constante macro)
__STDC_ISO_10646__(C++11) se développe en une constante entière de la forme yyyymmL, si wchar_t utilise Unicode, la date indique la dernière révision d'Unicode prise en charge.
(constante macro)
__STDC_MB_MIGHT_NEQ_WC__(C++11) s'étend à 1 si 'x' == L'x' pourrait être faux pour un membre du jeu de caractères de base, comme sur les systèmes basés sur EBCDIC qui utilisent Unicode pour wchar_t.
(constante macro)
__STDCPP_STRICT_POINTER_SAFETY__(C++11) s'étend à 1 si l'implémentation est stricte std::pointer_safety
(constante macro)
__STDCPP_THREADS__(C++11) s'étend à 1 si le programme peut avoir plus d'un fil d'exécution
(constante macro)

Les valeurs de ces macros (sauf pour __FILE__ et __LINE__) restent constantes tout au long de l'unité de traduction. Les tentatives de redéfinition ou d'indéfinition de ces macros entraînent un comportement non défini.

Note : dans la portée de chaque corps de fonction, il existe une variable prédéfinie spéciale locale à la fonction nommée. __func__(depuis C++11) définie comme un tableau de caractères statique contenant le nom de la fonction dans un format défini par l'implémentation. Il ne s'agit pas d'une macro de préprocesseur, mais elle est utilisée avec la variable __FILE__ et __LINE__par exemple par assert.

Macros de test des caractéristiques de la langue

Les macros suivantes sont prédéfinies dans chaque unité de traduction.

__cpp_aggregate_bases se développe vers le littéral entier 201603L.
(constante macro)
__cpp_aggregate_nsdmi se développe vers le littéral entier 201304L
(constante macro)
__cpp_aggregate_paren_init se développe vers le littéral entier 201902L
(constante macro)
__cpp_alias_templates se développe vers le littéral entier 200704L
(constante macro)
__cpp_aligned_new se développe vers le littéral entier 201606L
(constante macro)
__cpp_attributs se développe vers le littéral entier 200809L
(constante macro)
__cpp_binary_literals se développe vers le littéral entier 201304L
(constante macro)
__cpp_capture_star_this se développe vers le littéral entier 201603L
(constante macro)
__cpp_char8_t se développe vers le littéral entier 201811L
(constante macro)
__cpp_conditional_explicit se développe vers le littéral entier 201806L
(constante macro)
__cpp_constexpr se développe vers le littéral entier 201603L
(constante macro)
__cpp_coroutines se développe jusqu'au littéral entier 201902L
(constante macro)
__cpp_decltype se développe vers le littéral entier 200707L
(constante macro)
__cpp_decltype_auto se développe vers le littéral entier 201304L
(constante macro)
__cpp_deduction_guides se développe vers le littéral entier 201703L
(constante macro)
__cpp_delegating_constructors se développe vers le littéral entier 200604L
(constante macro)
__cpp_enumerator_attributes se développe vers le littéral entier 201411L
(constante macro)
__cpp_fold_expressions se développe vers le littéral entier 201603L
(constante macro)
__cpp_generic_lambdas se développe vers le littéral entier 201304L
(constante macro)
__cpp_guaranteed_copy_elision se développe vers le littéral entier 201606L
(constante macro)
__cpp_hex_float se développe vers le littéral entier 201603L
(constante macro)
__cpp_if_constexpr se développe vers le littéral entier 201606L
(constante macro)
__cpp_impl_destroying_delete se développe vers le littéral entier 201806L
(constante macro)
__cpp_impl_comparaison_à_trois_voies se développe vers le littéral entier 201806L
(constante macro)
__cpp_inheriting_constructors se développe vers le littéral entier 201511L
(constante macro)
__cpp_init_captures se développe vers le littéral entier 201304L
(constante macro)
__cpp_initializer_lists se développe vers le littéral entier 200806L
(constante macro)
__cpp_inline_variables se développe vers le littéral entier 201606L
(constante macro)
__cpp_lambdas se développe vers le littéral entier 200907L
(constante macro)
__cpp_ espace de noms_attributs se développe vers le littéral entier 201411L
(constante macro)
__cpp_noexcept_function_type se développe vers le littéral entier 201510L
(constante macro)
__cpp_nontype_template_args se développe vers le littéral entier 201411L
(constante macro)
__cpp_nontype_template_parameter_auto se développe vers le littéral entier 201606L
(constante macro)
__cpp_nontype_template_parameter_class se développe vers le littéral entier 201806L
(constante macro)
__cpp_nsdmi se développe vers le littéral entier 200809L
(constante macro)
__cpp_range_based_for se développe vers le littéral entier 201603L
(constante macro)
__cpp_raw_strings se développe vers le littéral entier 200710L
(constante macro)
__cpp_ref_qualifiers se développe vers le littéral entier 200710L
(constante macro)
__cpp_return_type_deduction se développe vers le littéral entier 201304L
(constante macro)
__cpp_rvalue_references se développe vers le littéral entier 200610L
(constante macro)
__cpp_sized_deallocation se développe vers le littéral entier 201309L
(constante macro)
__cpp_static_assert se développe vers le littéral entier 201411L
(constante macro)
__cpp_liaisons_structurées se développe vers le littéral entier 201606L
(constante macro)
__cpp_template_template_args se développe vers le littéral entier 201611L
(constante macro)
__cpp_threadsafe_static_init se développe vers le littéral entier 200806L
(constante macro)
__cpp_unicode_caractères se développe vers le littéral entier 200704L
(constante macro)
__cpp_unicode_literals se développe vers le littéral entier 200710L
(constante macro)
__cpp_user_defined_literals se développe vers le littéral entier 200809L
(constante macro)
__cpp_variable_templates se développe vers le littéral entier 201304L
(constante macro)
__cpp_variadic_templates se développe vers le littéral entier 200704L
(constante macro)
__cpp_variadic_using se développe vers le littéral entier 201611L
(constante macro)
(depuis C++20)

Exemple

#include// Make function factory and use it#defineFUNCTION(name, a)int fun_##name(){return a;}FUNCTION(abcd,12)FUNCTION(fff,2)FUNCTION(qqq,23)#undefFUNCTION#defineFUNCTION34#defineOUTPUT(a) std::cout <<"output: "#a<<'n'// Using a macro in the definition of a later macro#defineWORD"Hello "#defineOUTER(...) WORD #__VA_ARGS__intmain(){
    std::cout <<"abcd: "<<fun_abcd()<<'n';
    std::cout <<"fff: "<<fun_fff()<<'n';
    std::cout <<"qqq: "<<fun_qqq()<<'n';

    std::cout << FUNCTION <<'n';OUTPUT(million);//note the lack of quotes

    std::cout <<OUTER(World)<<'n';
    std::cout <<OUTER(WORD World)<<'n';}

Sortie :

abcd:12
fff:2
qqq:2334
output: million
Hello World
Hello WORD World

Voir aussi