Aller au menu - Aller au contenu

Le préprocesseur

Pour accéder à cette section
Connectez-vous !
connexion_rpx
Page 1 
Pseudo Commentaire
Page 1 
Hors ligne Adroneus # Posté le 09/01/2010 à 23:03:17
Avatar

Études : Epitech Toulouse

Aaaarf, Eh bien... Comme je te l'ai dit, tutoriel bien construit qui en aidera plus d'un!
Pour la partie sur les x-macros. Moi je suis pour que t'en rajoutes un peu ;) Après, faut voir les réactions des autres membres :p

En tous cas Gj
Hors ligne anonyme # Posté le 09/01/2010 à 23:14:37

Super tuto, ai rien compris mais c'est pas grave :D

Secret (cliquez pour afficher)
Citation : Cour

Rassurez-vous ça n'a rien à voir avec des trucs cochons :p .

Rhoo! Dommage :-° :D :p
Hors ligne Merkil # Posté le 09/01/2010 à 23:28:18
Avatar
Groupe : Bannis

Bon tuto.
Ça aidera tous ceux qui sortent des cours de Matéo21 avec des questions concernant les directives de préprocesseur.
 
Hors ligne anonyme # Posté le 09/01/2010 à 23:31:10

Et les defines pour les BSD ?
Hors ligne GurneyH # Posté le 10/01/2010 à 03:47:09
Avatar

Bon tutoriel, en plus on va enfin pouvoir comprendre tes codes :p .

Tu fais bien le tour des possibilité du préprocesseur tout en restant clair.

Concernant les X-MACROS, ton exemple d'utilisation est plutôt bien choisi. D'autres exemples, ici.

Ce serait mieux que tu donnes un exemple compilable directement, histoire qu'on puisse tester avec un simple copier/coller.

Je trouve que le choix de l'extension .h pour les fichiers extérieurs n'est pas une bonne idée. Autant attribuée une extension qui permette de trouver les définitions de X-MACROS rapidement.

Joli travail cependant.
 
Hors ligne Joe DRALLIAM # Posté le 10/01/2010 à 09:16:14
while(1)cout<<c++;
Avatar

Ville : Meudon
Pays : France métropolitaine

Il faudrait quand même indiquer qu'avec les macros il vaut toujours mieux mettre le maximum de parenthese :
Code : C
1
2
3
4
5
6
7
#define CARRE(x) x*x

int a = CARRE(5+3); // a vaut 5+3*5+3=5+(3*5)+3=23

#define CARRE2(x) ((x)*(x))

int b = CARRE2(5+3); // b vaut ((5+3)*(5+3))=(8*8)=64

Citation : Exemple de Qt
Computers are not intelligent. They think they are.
 
Hors ligne Pouet_forever # Posté le 10/01/2010 à 09:24:28
Trance forever :)
Avatar

Avis : Très bon

@ Schtroumpfette : C'est juste pour l'exemple, si tu veux mettre pour BSD tu le fais :p
D'ailleurs mon exemple n'est pas tout à fait correct parce que WIN32 est aussi défini sous WIN64 donc pas d'utilité de mettre defined(WIN64) ;)

@ GurneyH : Ah oui effectivement j'ai pas mis de code compilable directos :euh:
Il me semblait l'avoir fait pourtant ! Je vais le faire de suite :)
Pour l'extension c'est vrai, yen à qui mettent .h d'autre .def ^^
Moi je préfère le .h :D

@ Joe DRALLIAM :

Citation : moi
Notez que les parenthèses sont très importantes dans les macros dues à la priorité des opérateurs. Certaines peuvent être omises, d'autres non. Pour être sûr de ne pas avoir de mauvaise surprise je vous conseille d'abuser des parenthèses pour ne laisser aucune ambiguïté possible !

Image utilisateur
Image utilisateur
La musique du moment : Fictivision Vs. C-Quence - Symbols


[Le préprocesseur C]
Fan officiel de Tiësto !
 
Hors ligne sercus i # Posté le 10/01/2010 à 10:11:47
Forgotten.
Avatar

Bon tuto :) , pour une foi que je capte un truc ou presque !
Juste une petite question sur l'exemple des x-macros : Pourquoi faire un double const ?!
Code : C
1
char const * const marque_a [];

Sins can may be forgiven but conscience is a killer.
 
Hors ligne Pouet_forever # Posté le 10/01/2010 à 10:22:22
Trance forever :)
Avatar

Avis : Très bon

Un const pour le pointeur (donc tu ne peux pas changer l'adresse) et un autre pour les valeurs (tu ne peux pas les modifier) :)
C'est pas obligé mais c'est par précaution ;)

Image utilisateur
Image utilisateur
La musique du moment : Fictivision Vs. C-Quence - Symbols


[Le préprocesseur C]
Fan officiel de Tiësto !
 
Hors ligne anonyme # Posté le 10/01/2010 à 11:38:19

@Pouet_forever: ouais je sais mais je sais pas c'est quoi les defines pour les BSD... bon j'ai pas été chercher c'est vrai :-°
Hors ligne Despirithium # Posté le 10/01/2010 à 11:50:24
Open that shit up !
Avatar

Ça vaut la difficulté.

Je suis brutal de nature, ne m'en veuillez pas :-°
Et.. tu le ferais pour des Golden Grahams ?

Premier tutoriel : Interagir avec un serveur FTP !

Citation : Ben Venusos..
(19:06:36) Venusos: Sachant que le cul est ce qu'il-y a de plus rentable sur le net :noel:
Citation : Anthony
(21:38:43) Anthony: et après ben venir avec une gueule de cramé et les yeux rouges moi ça me gêne pas xD
Citation : Tweek
Anthony: Par contre
Anthony: depuis quelques jours
Anthony: mon frère se comporte comme un handicapé mental tétraplégique avec son torticolis
Anthony: j'te jure ça craint
Venusos: :noel:
Anthony: On dirait Tweek :noel:
Citation : Womanizer
(18:22:21) Anthony: putain
(18:22:32) Anthony: cette VenetiaPrincess elle fait quand même de bonnes vidéos
(18:23:26) Anthony: bon oui, cette phrase sorti de son contexte pourrait te faire croire à quelque chose de pervers
(18:23:44) Anthony: mais VenetiaPrincess c'est celle qui a fait la vidéo "Womanizer Parodie"
(18:23:53) Anthony: quand je regarde l'originale et la parodie c'est vachement bien fait
(18:24:14) Yann / big_nay: ouais j'avais vu ça ^^
(18:24:22) Anthony: nan mais toi je te fais pas confiance
Citation : Max aka un anonyme sur le SdZ
(17:02:10) Maximilien: tsé tant que ca marche qe le code soit propre ou pas on sen fou
Citation : Confirmation
(18:45:48) Anthony: "(17:02:10) Maximilien: tsé tant que ca marche qe le code soit propre ou pas on sen fou"
(18:46:00) -Dr3cK-: il a raison
Citation
(21:33:06) Venusos: shit j'ai des touches qui marchent plus
(21:33:10) Venusos: cradingues
(21:33:30) Anthony: stop manger des chips sur le clavier
(21:33:45) Venusos: pas un brin
(21:33:51) Anthony: stop gerber
(21:33:54) Venusos: non plus
(21:34:04) Anthony: stop fap
(21:34:19) Venusos: :noel:

Citation : Nouveautés
(22:33:24) Maximilien: Salut Blackis.
(22:33:29) Maximilien: Comment vas-tu?
(22:33:38) Maximilien: Que fais-tu?
(22:33:45) Maximilien: Quoi de nouveau?
(22:33:48) Anthony: Oh
(22:33:50) Anthony: Salut max
(22:33:56) Anthony: ben là je parle à des filles
(22:34:01) Anthony: ça réponds aux trois questions
Citation : Rattrapage
(21:09:01) † Sterinaoe †: juste quand j'ai rien a foutre
(21:09:13) Anthony: en gros t'as rien à foutre quoi
(21:09:22) † Sterinaoe †: ouaaaaai
(21:09:30) Anthony: ::
(21:09:32) Anthony: :!
(21:09:38) Anthony: merdeUH
(21:09:40) Anthony: :/
(21:09:42) Anthony: VOILA
Citation : Histoire d'intérets
(11:00:04) Anthony: (a)
(11:00:14) *naf ·#·$3[ Guigui ]·$ - On Holidays!·0: ?
(11:00:33) Anthony: nan rien j'voulais savoir ce que ça faisait le "( a )"
(11:00:38) Anthony: et sinon ça va ?
Citation : Accident..
(13:18:32) Yann / big_nay: (dis comme ça, on dirait que c'est une radine :-°)
(13:18:42) Anthony: non mais c'est vrai
(13:19:00) Anthony: il manque un centime la maison ça devient Tchernobyl
 
Hors ligne 78uzg76fq # Posté le 10/01/2010 à 23:28:27
Avatar

Intéressant. J'ai exa là-dessus dans peu de temps, ça pourra me servir. ;)
Connecté SpaceFox # Posté le 11/01/2010 à 00:12:28
Utilise ton cerveau !
Avatar
Validateurs
Flux RSS

Études : UTT

Tuto original, utile et intéressant.
Je rajouterais juste un gros avertissement au début sur la lisibilité des codes produits si on fait pas gaffe (ceux qui connaissent l'IOCCC savent de quoi je parle :D) :
Code : C
1
2
3
4
#define x =
#define double(a,b) int
#define char k['a']
#define union static struct

Image utilisateur
 
Hors ligne Dagrut # Posté le 11/01/2010 à 07:40:37
BLACK OUT
Avatar

Pour les defines spécifiques aux systèmes d'exploitation, j'avais trouvé ça, il y a un an ou deux : http://predef.sourceforge.net/preos.html. Il faut cependant prendre soin de tester tout les defines proposées. Chez moi, par exemple, "__linux" est défini, mais "linux" ne l'est pas.
 
Hors ligne Darkelfe # Posté le 12/01/2010 à 08:11:25
Apprendre tout sur tout
Avatar

Ville : Brignais
Pays : France métropolitaine
Études : IUT A Lyon 1

Bon tuto, je ne connaissais pas les X_MACRO.

Par contre, en même temps que #error, il existe #warning.

Citation
La négligence du détail détruit l'intelligence de la conception.


Un jeu simple mais addictif ? Minecraft !
 
Hors ligne prs513rosewood # Posté le 28/01/2010 à 23:25:35
The misspelled bulldog
Avatar
Groupe : Anciens

Ville : Lausanne
Pays : Suisse
Études : EPFL

Bon tutoriel. Je ne connaissais pas les macros à nombre variable d'arguments. C'est super pratique pour s'affranchir du bon vieux NSLog() en ObjC, et repasser au printf(), mais ObjC-style. ^^
 
Hors ligne Arthurus # Posté le 16/03/2010 à 22:13:14
Everyday I'm shuffling
Avatar
Validateurs

Études : Ensimag

Pouet, ce serait bien que tu parles de l'option -D de gcc (perso quand je l'avais découverte, ma vie avait basculé).
Et puis aussi l'option -E me semble une bonne manière de débugger les progs qui utilisent beaucoup les préproce
 
Hors ligne candide # Posté le 05/05/2010 à 01:27:19
"In C ode we trust"
Avatar

Le préprocesseur est une question difficile. Le tuto est correct, en particulier par rapport à ce qu'on peut trouver dans les ouvrages, il peut à l'occasion apporter des éclaircissements utiles. Néanmoins, la clarté et la complétude des explications ne sont pas à la hauteur de la difficulté de la notion à expliquer. Il y aurait de nombreux points à reprendre, à préciser, à contextualiser, à ajouter. La remarque d'Arthurus concernant le non-traitement de l'option -E de gcc est tout à fait pertinente : savoir utiliser l'option -E est d'une aide précieuse pour apprendre le fonctionnement du préprocesseur C.


Juste deux petites remarques sur le contenu (mais rien de bien méchant ;) ) :


Citation : Pouet_Forever
La directive defined fait la même chose que le #ifdef


Pas clair. defined n'est pas une directive du préprocesseur, c'est un opérateur. La sémantique de defined n'a rien à voir avec celle de #ifdef bien qu'une expression defined est utilisée au sein d'une directive d'inclusion condionnelle.

Les exemples d'utilisation de defined :

Citation : Pouet_Forever

Code : C
1
2
3
4
5
#if defined (__APPLE__) || defined ( linux )
# include <unistd.h>
#elif defined ( WIN32 ) || defined ( WIN64 )
# include <windows.h>
#endif





laisseraient penser qu'il s'utilise toujours sous la forme defined(toto). Or, il n'en est rien, defined n'est pas une fonction ou une macro fonction, c'est un opérateur comme sizeof et il admet aussi la syntaxe

Code : C
1
defined toto

Citation : Pouet_Forever

On va commencer par la plus simple : l'opérateur nul !
C'est tout simplement le # sans rien derrière (éventuellement des espaces/tabulations ou commentaires).


Petit problème de vocabulaire là aussi. Employé ainsi, # n'est pas un opérateur, c'est ce qu'on appelle la directive nulle. Quand on parle de l'opérateur #, on parle uniquement de l'opérateur de "stringization ".

  • Make it work, Make it well, Make it fast, Make it short, Make it fun
  • Comment insérer les balises de code dans un message ? : Screencast ou Texte
  • Le rasoir d'Occam : Entities should not be multiplied beyond necessity.
  • KISS !
  • Le gâteau sous la cerise.
  • (Lien vers fichier pdf) La norme du langage C 99
  • scanf et printf : les colifichets de la programmation bling bling

 
Hors ligne Quentin Guibert # Posté le 24/05/2010 à 22:51:08
Avatar

Ville : Saint martin de valgalgues
Pays : France métropolitaine

Bonjour,

Citation
defined n'est pas une fonction ou une macro fonction, c'est un opérateur comme sizeof et il admet aussi la syntaxeCode : C
1
defined toto


Oui, mais attention, 'sizeof' et 'defined' ont beau être tous les deux des opérateurs un-aires, ils n'ont aucun lien !

L'expression suivante :

Code : C
1
2
#if defined XXX
...


est équivalente à :

Code : C
1
2
#if defined(XXX)
...


Là, on est d'accord, mais avec l'opérateur d'arité un-aire 'sizeof', la syntaxe est importante.

Si l'ont veut obtenir la taille d'un objet, on fait ceci :

Code : C
1
(void) printf ("\nsizeof objet : %u\n", sizeof objet) ;


Si l'ont veut obtenir la taille d'un type, on doit faire ceci (je rajoute que l'ont peut aussi utiliser cette syntaxe pour obtenir la taille du résultat d'un objet mais on ne peut pas faire le contraire) :

Code : C
1
(void) printf ("\nsizeof (type) : %u\n", sizeof (type)) ;


La syntaxe dépend donc de l'expression avec l'opérateur un-aire 'sizeof' contrairement à l'opérateur un-aire 'defined'. Bon, je sais que tu le sais, mais voilà. :p

Pour le tutoriel, il serait bien de préciser que le préprocesseur évalue les données selon l'algèbre booléenne. Par exemple :
Code : C
1
2
3
4
#define XXX

#if defined XXX /* Après analyse, l'expression 'defined XXX' sera remplacée par '1' */
...


On peut donc utiliser, dans nos expressions, utiliser les opérateurs logiques '&&', '||', '!'...

Tu pourrais aussi parler de la directive de préprocesseur '#warning' qui émet une alerte au lieu d'avorter la compilation comme le fait la directive de préprocesseur '#error' (enfin, la directive de préprocesseur '#warning' émet une alerte uniquement si l'option -Werror de GCC n'est pas indiqué).

Sinon le hic' du tutoriel, c'est que tu ne présente pas la vrai capacité du préprocesseur. Tu n'expliques pas ce qu'il fait concrètement et dans quel ordre il analyse les jetons.
Comme ça, tu pourrais parler de l'ablation des commentaires, des antislash en fin de ligne, des séquences trigraphe... À un moment, tu parles de l'alignement des données en mémoire, pourquoi ne pas parler de la macro 'offsetof' ?

Il manque aussi une partie qui présente quelques constantes symboliques prédéfinies.
Par exemple les constantes symboliques '__func__' qui vaut le nom de la fonction où se trouve le remplacement (attention, c'est une implémentation de la norme C99), '__FUNCTION__' qui vaut aussi le nom de la fonction où se trouve le remplacement (là cette fois, c'est une implémentation de GCC), '__ASSEMBLER__' qui est définit à la valeur 1 lors de l'étape de prétraitement du code source assembleur et '__STDC_HOSTED__' qui est définit à la valeur 1 si l'ensemble de la bibliothèque standard du langage C est installé.

Tu ne parle même pas des deux constantes symboliques les plus importantes, la constante symbolique '__STDC_VERSION__' et la constante symbolique '__STDC__' qui vaut 1 si le compilateur se conforme à la norme ISO C (certains compilateur ne définisse pas la constante symbolique '__STDC__' à la valeur 1 mais à la valeur 0).

Tu pourrais aussi dire que en langage C++, on peut utiliser des mots à la place certains opérateurs. Voici une liste :

and &&
and_eq &=
bitand &
bitor |
compl ~
not !
not_eq !=
or ||
or_eq |=
xor ^
xor_eq ^=

Pour utiliser ces mots en langage C, on peut tout simplement inclure le fichier d'interface 'iso646.h'.

Dernière chose, qui selon moi est très important, tu oublies de dire que les macros variadics sont des implémentations de la norme C99. o_O

Voici une liste des constantes symboliques prédéfinies standard :
http://gcc.gnu.org/onlinedocs/cpp/Stan [...] efined-Macros

Et une liste des constantes symboliques prédéfinies de l'implémentation GNU :
http://gcc.gnu.org/onlinedocs/cpp/Comm [...] efined-Macros
Hors ligne Quentin Guibert # Posté le 26/05/2010 à 22:23:42
Avatar

Ville : Saint martin de valgalgues
Pays : France métropolitaine

Oups, double-post...
Hors ligne Arthurus # Posté le 31/05/2010 à 03:54:38
Everyday I'm shuffling
Avatar
Validateurs

Études : Ensimag

@Quentin Guibert : Je ne suis pas d'accord avec toi. Si Pouet prend en compte toutes tes remarques, le tuto deviendra vraiment trop chargé, avec des fois des informations limite inutiles.
Qu'il parle de #warning ok, ça peut passer, mais lui demander de parler de toutes les constantes prédef que tu as évoquées, franchement y'a les docs pour ça !
Un lecteur du tuto quand il finira sa lecture, s'il est intéressé par ce domaine il fera des recherches dans des endroits bien plus précis et détaillés que le site du zéro.
N'oublions pas que c'est un site destiné aux débutants, bien que ce tuto soit plus pour des débutants avertis disons, cela n'empêche qu'il ne faut pas le charger par crainte qu'il ne soit lu à la fin que par des gens qui connaissent très bien le domaine, ce qui au final ne servira à rien.
 
Hors ligne Quentin Guibert # Posté le 05/06/2010 à 21:58:22
Avatar

Ville : Saint martin de valgalgues
Pays : France métropolitaine

@Arthurus : Oui j'avoue, j'ai un peu poussé sur les constantes symboliques prédéfinies...

Mais je pense toujours qu'il y a beaucoup de choses à rajouter dans ce tutoriel...

Par exemple, l'ablation des commentaires serait selon moi, une des premières chose à voir quand on étudie le programme de préprocesseur (tu peux pas dire le contraire là :D ) ! En plus, en une/deux ligne(s), c'est tout expliqué !

Idem pour les constantes symboliques qui indiquent dans quelle norme du langage on se conforme (enfin, c'est un peu plus long à expliquer ça)...
Hors ligne uknow # Posté le 14/09/2010 à 00:31:21
chercher est un art
Avatar

Ville : Paris
Pays : France métropolitaine
Études : CNAM

Bon tutoriel félicitation.

Par contre, mettre les utilisateurs des macros en garde contre des erreurs classiques peut être utile :) :

Exemple 1 :

Code : C
1
2
3
#define CARRE(a) (a*a)

a2 = CARRE(a++);


Exemple 2 :

Code : C
1
2
3
4
5
6
#define AJOUTER(a,b)  (a + b);

if(condition)
    c = AJOUTER(a,b);
else
    d = AJOUTER(b,c);


Exemple 3 :

Code : C
1
2
3
4
5
6
7
8
#define AJOUTER(a, b, c)                        \
                      printf("%d + %d ", a, b); \
                      c = a + b;                \
                      printf("= %d\n", c);


while (i++ < 10)
    AJOUTER(n, 1, n);
 
Hors ligne Macros Le Noir # Posté le 13/01/2011 à 19:39:10
Fonscar
Avatar

Ville : Versoix
Pays : Suisse

Je n'ai remarqué aucune virgule, surtout pas dans l'introduction.

Mon tutoriel sur le cracking

Tutoriel Assembleur en cours de rédaction :) ! Plus d'infos ici et bêta test ici
Participe aussi à la relecture d'un tuto sur l'architecture matérielle des ordinateurs rédigé par mewtow. :) Plus d'infos ici et bêta test ici.
When I smoke my Weed, I feel so free, juste like a Ganja tree <3 .
 
Pour accéder à cette section
Connectez-vous !
connexion_rpx