Analyse et programmation 2

Le préprocesseur

Thèmes abordés
• Le préprocesseur
– Rôle et fonctionnement

• L’inclusion de fichiers
– Les directives include

• Comment compiler différentes variantes d’un programme
– La compilation conditionnelle

• Automatiser des tâches de programmation
– Les macros

• Les techniques avancées
– autres directives

• Comment utiliser judicieusement le préprocesseur
– Les limites pratiques
Analyse et programmation 2 - Le préprocesseur 1

1

Préprocesseur de texte Code source complet Processus de compilation 2.c 1.rappel main.lib stdlib.Le préprocesseur 2 Le préprocesseur Présentation • Effets – Procède principalement à d du remplacement de te texte te po pour r produire un fichier source compilable complet.Le préprocesseur Rôle et position dans la chaîne de compilation . • Directives préprocesseur – Elles commencent par le caractère spécial # – Les directives standards #define #error #elif #else #include #line #endif #pragma #if #ifdef #undef #ifndef Analyse et programmation 2 .h 3. Compilateur main. Editeur de liens Exécutable complet Analyse et programmation 2 .o crt.h stdio. – Le fichier transformé est ensuite transmis au compilateur.Le préprocesseur 3 2 .

Le préprocesseur 4 Définition de symboles La directive #define • Syntaxe #define Symbole Pas de point virgule final.h" • Fonction – Le préprocesseur remplace cette directive par le fichier spécifié. fait partie du texte de remplacement Texte de remplacement • Effet – Agit sur le code source situé après sa définition.h> • ne recherche le fichier mentionné que dans les répertoires de bibliothèque par défaut. – Toutes les occurrences de « Symbole » sont remplacées par le texte de remplacement. • Ces répertoires peuvent en général être configurés – dans l’environnement de développement – par une variable d’environnement du système d’exploitation. puis comme l’autre forme. – Texte de remplacement peut être vide. Analyse et programmation 2 . } Analyse et programmation 2 . • Exemple #define afficher printf int main() { afficher("Hello World !\n"). Si présent.h" • Recherche d’abord dans le répertoire du projet. – Symbole doit être un identificateur valide.Inclusion de fichiers Syntaxe et effet • Syntaxes #include <stdio <stdio. – La forme #include <stdio. – La forme #include "monfichier.Le préprocesseur 5 3 . La symbole est quand même défini. system("PAUSE").h> h> #include "monfichier.

Le préprocesseur 6 Définition de symboles La directive #define . – Elle a un impact p catastrophique p q sur la lisibilité.8.8. il s’agit d’un remplacement textuel • Effets inattendus possibles • Exemple #define TEMPERATURE_MAX 80 + 20 float temperature. – Elle est donc hautement déconseillée. // 80 % // résultat obtenu : temperatureMax = 80 + 20 * 0. // 96 ! Analyse et programmation 2 . • Attention.Définition de symboles La directive #define .pièges • Effectue un remplacement de symboles – Donc pas de remplacement dans les chaînes de caractère littérales. temperature = TEMPERATURE_MAX * 0.Le préprocesseur 7 4 . • Utilisation habituelle #define TEMPERATURE_MAX 100 Analyse et programmation 2 .recommandations • Toujours tout mettre entre parenthèses ! #define TEMPERATURE_MAX TEMPERATURE MAX (80 + 20) • Cette directive permet de créer un langage synonyme #define POUR for #define TANT_QUE while #define FAIRE do – Cette utilisation n’apporte rien en fonctionnalité.

automatiquement – Certains symboles font partie de la norme ANSI. – En général. __LINE__). • Symboles standardisés __DATE__ __FILE__ __LINE__ __STDC__ __TIME__ __TIMESTAMP__ Analyse et programmation 2 . • Pour améliorer la lisibilité – Il est possible de le répartir sur plusieurs lignes. – On indique que texte se poursuit sur la ligne suivante en terminant une ligne avec le caractère ‘\’ • Exemple – Symbole pour afficher une trace du passage du programme. Définie à 1 si le compilateur respecte le standard C ANSI. Chaîne littérale contenant le nom du fichier source. #define TRACE printf("Le programme est passe " \ " dans le fichier %s" \ " ligne %d\n".Le préprocesseur 8 Définition de symboles Symboles créés automatiquement • Lors du traitement par le préprocesseur – Un certain nombre de symboles sont définis automatiquement. Chaîne littérale contenant la date/heure de dernière modification du fichier source 9 5 . Analyse et programmation 2 .Le préprocesseur Chaîne littérale contenant la date de compilation du fichier. Chaîne littérale contenant l’heure de compilation du fichier.Définition de symboles La directive #define – définitions multilignes • Les textes de remplacement – Peuvent être très longs. \ __FILE__. les compilateurs ajoutent de nombreux symboles spécifiques. longs – Deviennent alors peu lisibles. Numéro de la ligne en cours de compilation.

Analyse et programmation 2 .Le préprocesseur 10 Définition de symboles Annuler une définition de symbole • Syntaxe # d f Symbole #undef S b l • Effet – Après cette directive. – Cela permet de modifier globalement les caractéristiques d’un programme. p • Application – On peut ainsi garder un même code source qui peut basculer très facilement entre environnement de simulation et réel. – Attention : certains compilateurs acceptent une redéfinition d d’un un symbole déjà défini Analyse et programmation 2 . – En général. – Fonctionne même si Symbole n’était pas encore défini. – Il est alors possible de donner une nouvelle définition à ce symbole. • Dans un fichier à inclure – On peut créer un fichier . dans les propriétés du projet.h contenant des définitions de symbole permettant de transformer le code.Le préprocesseur 11 6 .Définition de symboles Définir des symboles globalement • Au niveau de l’IDE – De nombre nombreux IDE permettent de définir des symboles s mboles globalement globalement. le symbole n’est plus défini.

– Une macro peut avoir 0 paramètres. – Elle est créée avec #define comme un symbole sans paramètres. Elle doit alors être utilisée en mentionnant (). param2) Texte de remplacement • Effet – La macro est expansée • Les paramètres sont reportés dans le texte de remplacement. ((10) > (15) ? (10) : (15)) ). Analyse et programmation 2 . – Le texte de remplacement obtenu remplace la macro dans le code source. • Syntaxe #define Nom(param1. // après expansion : printf("%d\n". } Analyse et programmation 2 . 15)). MAX(10.Le préprocesseur 13 7 . Y) ((X) > (Y) ? (X) : (Y)) int main() { printf("%d\n".Le préprocesseur 12 Les macros Exemple 1 #define MAX(X.Les macros Présentation • Définition – Une macro correspond à une ne définition paramétrée paramétrée. system("PAUSE").

} Analyse et programmation 2 . MAX(++i. Y) ((X) > (Y) ? (X) : (Y)) int main() { int i. 0. --k)). } Analyse et programmation 2 . i < 10. valeur). – Et non pas d’une d une fonction fonction. i++) ) { somme += i. \ __FILE__. la variable %s vaut %d\n". k. __LINE__. i) } system("PAUSE"). nom. int somme.Les macros Exemple 2 #define TRACE_INT(nom. for o ( (i = 0. i = 8. somme = 0.Le préprocesseur 15 8 . TRACE_INT("i". – L’évaluation des paramètres est gérée différemment ! • Exemple #define MAX(X. // Affiche 10 ! system("PAUSE"). valeur) \ printf( \ "TRACE a au passage dans le fichier %s " \ "a la ligne %d.Le préprocesseur 14 Les macros Les pièges • Toujours penser qu’il s’agit d’un remplacement de texte. printf ( "%d\n". int main() { int i. k = 9.

} Analyse et programmation 2 . #variable. i##n) int main() { int i1 = 10. int i2 = 20. – Permet de construire des noms de variables à partir du texte passé en paramètre à une macro. la variable %s vaut %d\n". system("PAUSE"). __LINE__. demo_token_paster(3). demo_token_paster(1).Les macros Opérateurs spéciaux • Opérateur # (stringizing operator) – Transforme le paramètre placé après # en chaîne littérale • Exemple #define TRACE_INT(variable) \ printf( \ "TRACE au passage dans le fichier %s " \ "a la ligne %d. • Exemple #define demo_token_paster(n) printf("i" #n " = %d".Le préprocesseur 17 9 . \ __FILE__. variable). "i" pour TRACE_INT(i) Analyse et programmation 2 . int i3 = 30.Le préprocesseur 16 Les macros Opérateurs spéciaux • Opérateur ## (token pasting operator) – Concatène le paramètre placé avant ou après avec le texte de la macro. demo_token_paster(2).

Le préprocesseur 18 La compilation conditionnelle Directives #if • Forme générale #if condition1 // zone compilée #elif condition2 // zone compilée #elif condition3 // zone compilée #else // zone compilée #endif si condition1 est vraie si condition2 est vraie si condition3 est vraie si aucune condition vraie • Les directives #elif et #else sont optionnelles. • Formes contractées #ifdef symbol #ifndef symbol équivalent à équivalent à #if defined(symbol) #if !defined(symbol) Analyse et programmation 2 . – Les erreurs de syntaxe ne sont pas détectées. #endif • Effet – Si le symbole DEBUG est défini. code • Forme équivalente #ifdef DEBUG printf("Mode debug\n"). – Penser à tester toutes les variantes du code.La compilation conditionnelle Directives #if • Syntaxe #if defined(DEBUG) ( ) printf("Mode debug\n"). #endif Analyse et programmation 2 . le code entre if et endif fera partie du code source compilé. – Dans le cas contraire.Le préprocesseur 19 10 . tout ce code sera supprimé.

h" #else #include "anglais.Rechercher un titre" • anglais. selon la syntaxe du C – Seulement des expressions statiques (SYMBOLE == 2) && defined(DEBUG) Analyse et programmation 2 . inclure un fichier qui définit les chaînes de caractères dans cette langue #ifdef FRANCAIS #include "francais.h #define TEXTE_CHOIX "Choice :" #define TEXTE_CHOIX1 "1.Le préprocesseur 20 Applications Internationalisation d’une application • En fonction d’un symbole de langue.La compilation conditionnelle Directives #if – les conditions utilisables • Existence d’un symbole defined(SYMBOLE) • Egalité d’un symbole SYMBOLE == 2 • Expressions complexes.h #define TEXTE_CHOIX "Choix :" #define TEXTE_CHOIX1 "1.Le préprocesseur 21 11 .h" #endif • francais.Find a book" Analyse et programmation 2 .

On ? 1 : 0) #endif } Analyse et programmation 2 . __LINE__. d’e éc tion • Exemple #ifdef DEBUG #define TRACE_INT(variable) \ printf( \ "TRACE au passage dans le fichier %s " \ "a la ligne %d. release on ne veut e t plus pl s les traces d’exécution. \ __FILE__.Le préprocesseur 22 Applications Basculement entre version DEBUG et RELEASE d’une application • Passage mode debug à release – En mode release. On ? 2 : 0) #endif } void SetHeater(int On) { #ifdef MODE_REEL SetOutputBit(0x10FD.Applications Génération de code en fonction de l’environnement • Passage entre un environnement de simulation et un environnement réel en modifiant une seule définition.Le préprocesseur 23 12 . • Exemple void SetMotor(int On) { #ifdef MODE_REEL SetOutputBit(0x10FA. variable). #variable. la variable %s vaut %d\n". #else #define TRACE_INT(variable) #endif Analyse et programmation 2 .

Le préprocesseur 25 13 .Le préprocesseur 24 Le préprocesseur Autres directives standard . 1) . #pragma pack(pop) . • Le texte qui suit pragma est spécifique au compilateur. – tel qu’il apparaitra dans le log du compilateur. spécifiques • Ces options peuvent être activées ou désactivées lors de la compilation en utilisant la directive pragma.Le préprocesseur Autres directives standard – générer une erreur de compilation • Utiliser la directive #error • Cette C tt directive di ti doit d it êt être suivie i i – par le message d’erreur en clair..packing is 8 Analyse et programmation 2 . • Exemple #if MODE == 1 #define Kp 10 #elif MODE == 2 #define Kp 12.#pragma • Chaque compilateur et chaque plateforme a des options spécifiques.5 #else #error Valeur de MODE invalide #endif Analyse et programmation 2 ..packing is now 1 // . • Exemple – Visual Studio 2005 #pragma pack(push.

et les pièges associés.Qu’avons-nous appris ? • Le préprocesseur permet – – – – D inclure des fichiers d D’inclure d’en en tête ou de code. t t • Environnement réel. De générer du code avec des macros. Analyse et programmation 2 .Le préprocesseur 27 14 . – Génération de programmes différents en fonction d’une définition • Version anglaise.Le préprocesseur 26 Vos questions Analyse et programmation 2 . – Adaptation Ad t ti rapide id d du code d à diffé différents t contextes. code De redéfinir des symboles. simulation. … • Ne pas en abuser. De compiler conditionnellement du code. • Applications – Basculement entre mode avec et sans trace • Tout en conservant le code d’écriture des traces. française.

Analyse et programmation 2 .Le préprocesseur 28 15 .

Sign up to vote on this title
UsefulNot useful