#define, directive (C/C++)

Le #define crée une macro, qui est l’association d’un identificateur ou d’un identificateur paramétrable avec une chaîne de jeton. Une fois la macro définie, le compilateur peut substituer la chaîne de jeton pour chaque occurrence de l'identificateur dans le fichier source.

Syntaxe

#define identificateur token-stringopt
#define identifier(identificateur opt, ... ,identifieropt)token-string opt

Notes

La directive #define permet au compilateur de remplacer la chaîne de jeton pour chaque occurrence d’identificateur dans le fichier source. L’identificateur est remplacé uniquement lorsqu’il forme un jeton. Autrement dit, l’identificateur n’est pas remplacé s’il apparaît dans un commentaire, dans une chaîne ou dans le cadre d’un identificateur plus long. Pour plus d’informations, consultez Jetons.

L’argument de chaîne de jeton se compose d’une série de jetons, tels que des mot clé s, des constantes ou des instructions complètes. Un ou plusieurs caractères d’espace blanc doivent séparer la chaîne de jeton de l’identificateur. Cet espace blanc n'est pas considéré comme faisant partie du texte substitué, pas plus que tout espace blanc qui suit le dernier jeton du texte.

Un #define sans chaîne de jeton supprime les occurrences d’identificateurdu fichier source. L’identificateur reste défini et peut être testé à l’aide des directives et #ifdef des #if defined directives.

La deuxième forme de syntaxe définit une macro de type fonction avec des paramètres. Cette forme accepte la liste facultative des paramètres qui doivent apparaître entre parenthèses. Une fois la macro définie, chaque occurrence suivante d’identificateur( identificateur opt, ..., identificateuropt) est remplacée par une version de l’argument de chaîne de jeton qui a des arguments réels substitués pour les paramètres formels.

Les noms de paramètres formels apparaissent dans la chaîne de jeton pour marquer les emplacements où les valeurs réelles sont remplacées. Chaque nom de paramètre peut apparaître plusieurs fois dans la chaîne de jeton, et les noms peuvent apparaître dans n’importe quel ordre. Le nombre d'arguments de l'appel doit correspondre au nombre de paramètres de la définition de macro. L'utilisation répandue des parenthèses garantit que les arguments réels complexes sont interprétés correctement.

Les paramètres formels de la liste sont séparés par des virgules. Chaque nom contenu dans la liste doit être unique et la liste doit être placée entre parenthèses. Aucun espace ne peut séparer l’identificateur et la parenthèse ouvrante. Utilisez la concaténation de ligne : placez une barre oblique inverse (\) immédiatement avant le caractère de ligne de nouvelle ligne pour les directives longues sur plusieurs lignes sources. L’étendue d’un nom de paramètre formel s’étend à la nouvelle ligne qui met fin à la chaîne de jeton.

Lorsqu’une macro a été définie dans la deuxième forme de syntaxe, les instances textuelles suivantes suivies d’une liste d’arguments indiquent un appel de macro. Les arguments réels qui suivent une instance d’identificateur dans le fichier source sont mis en correspondance avec les paramètres formels correspondants dans la définition de macro. Chaque paramètre formel dans la chaîne de jeton qui n’est pas précédé d’une chaîne (#), de charizing (#@) ou d’un opérateur de collage de jetons (##) ou non suivi d’un ## opérateur, est remplacé par l’argument réel correspondant. Toutes les macros figurant dans l'argument réel sont développées avant que la directive ne remplace le paramètre formel. (Les opérateurs sont décrits dans Opérateurs de préprocesseur.)

Les exemples de macros suivants avec des arguments illustrent la deuxième forme de la syntaxe #define :

// Macro to define cursor lines
#define CURSOR(top, bottom) (((top) << 8) | (bottom))

// Macro to get a random integer with a specified range
#define getrandom(min, max) \
    ((rand()%(int)(((max) + 1)-(min)))+ (min))

Les arguments avec des effets secondaires provoquent des résultats inattendus générés par les macros. Un paramètre formel donné peut apparaître plusieurs fois dans la chaîne de jeton. Si ce paramètre formel est remplacé par une expression à effets secondaires, l'expression, avec ses effets secondaires, peut être évaluée plusieurs fois. (Voir les exemples sous Opérateur Token-Pasting (##).)

La directive #undef entraîne l'oubli de la définition de préprocesseur d'un identificateur. Pour plus d’informations, consultez la directive #undef.

Si le nom de la macro en cours de définition se produit dans la chaîne de jeton (même en raison d’une autre extension de macro), il n’est pas développé.

Une deuxième #define pour une macro portant le même nom génère un avertissement, sauf si la deuxième séquence de jetons est identique à la première.

Section spécifique à Microsoft

Microsoft C/C++ vous permet de redéfinir une macro si la nouvelle définition est syntaxiquement identique à la définition d'origine. En d'autres termes, les deux définitions peuvent avoir des noms de paramètres différents. Ce comportement diffère de ANSI C, ce qui exige que les deux définitions soient identiques de façon lexicale.

Par exemple, les deux macros suivantes sont identiques, sauf pour les noms de paramètres. ANSI C n’autorise pas une telle redéfinition, mais Microsoft C/C++ la compile sans erreur.

#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )

En revanche, les deux macros suivantes ne sont pas identiques et généreront un avertissement dans Microsoft C/C++.

#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )

FIN de la section spécifique à Microsoft

Cet exemple illustre la directive #define :

#define WIDTH       80
#define LENGTH      ( WIDTH + 10 )

La première instruction définit l'identificateur WIDTH en tant que constante entière 80, puis définit LENGTH en tant que WIDTH et la constante entière 10. Chaque occurrence de LENGTH est remplacée par (WIDTH + 10). Ensuite, chaque occurrence de WIDTH + 10 est remplacée par l'expression (80 + 10). Les parenthèses autour de WIDTH + 10 sont importantes car elles contrôlent l'interprétation d'instructions telles que :

var = LENGTH * 20;

Après l'étape de prétraitement, l'instruction devient :

var = ( 80 + 10 ) * 20;

ce qui correspond à 1800. Sans parenthèses, le résultat est :

var = 80 + 10 * 20;

qui prend la valeur 280.

Section spécifique à Microsoft

La définition de macros et de constantes avec l’option du compilateur /D a le même effet que l’utilisation d’une directive de prétraitement #define au début de votre fichier. Jusqu'à 30 macros peuvent être définies avec l'option /D.

FIN de la section spécifique à Microsoft

Voir aussi

Directives de préprocesseur