salut,
pourquoi dans le repertoire le fichier stdio.h du repertoire \Dev-Cpp\include le header est définit comme ça::
...
ce qui me gêne ce sont tous ces underscore. Pourquoi _STDIO_H_ et pas STDIO_H ou stdio.h ?
Ah aussi j'ai oublié de demander comment ça peut marcher vu qu'on inclut que le fichier .h, ya pas les definitions de fonctions dedans, on devrait inclure le .c normalement non? également comment le nom peut il correspondre à stdio.h avec tous ces _
merci
Les "#ifndef _STDIO_H_ #define _STDIO_H_ #endif /* _STDIO_H_ */ " qui encadrent les .h ne servent qu'a éviter qu'un .h soit inclue plusieurs fois ce qui foutrait la merde à la compilation.
Les underscore partout sont une sorte de norme pour éviter que ces define posent problème dans le code :
si tu met "#define stdio.h" à la place, et que tu définie une structure stdio avec un champ h à l'intérieur, ça peut poser pas mal de problèmes.
"Pourquoi on inclue un .h et pas un .c?"
La création d'un exécutable se fait en 2 grosses phases : compilation et édition de lien.
Pour compiler (transformer un .c en .o, càd du code exécutable mais les références à des symboles (fonctions, variables) externes ne sont pas résolues), il n'y a besoin que du prototype des fonctions (leur type de retour et leurs arguments) et structures de données.
Pour l'édition de lien, c'est là que les références aux symboles externes sont résolues, si tu compile plusieurs .c, les différents .o seront fusionnés en gros, si tu appelles des fonctions de stdio.h, l'exécutable sera "configuré" pour aller chercher les fonctions définies dans stdio.h dans un .so ou .dll à l'exécution.
(ce que je viens de dire est loin d'être complet, mais une explication détaillée serait beaucoup plus (trop) longue)
Bref si ce qui t'as amené à te poser ces questions c'est que tu voulais voir le code de printf :
Tu ne le trouveras pas dans les fichier de Dev-cpp, le code est précompilé dans des .lib et .dll.
Si tu veux le trouver, la glibc est une implémentation libre de la libc, et tu dois pouvoir trouver les sources quelques part sur internet.
ok merci
donc en gros le define qu'on met dans un .h c'est le nom qu'on veut. En fait je croyais que quand on faisait #define _STDIO_H_ on définissait le .h. j'étais influencé par java je croyais que ce nom devait etre le meme que celui du fichier mais en fait ça n'a rien à voir. Au fond alors _STDIO_H_ n'est qu'une constante qui servira a ne pas inclure plusieurs fois l'entete ? vu que à la premeire inclusion on va definir la constante
je veux dire : le préprocesseur va inclure l'entete une premiere fois ça va definir la constante qu'on met dans le .h, et si jamais il y une autre tentative d'inclusion, grâce à la condition l'entete ne sera pas de nouveau incluse vu que la constante aura été définie a la premiere inclusion.
Mais on utilise un espace memoire pour rien non a definir une constante comme ça ?
"je veux dire : le préprocesseur va inclure l'entete une premiere fois ça va definir la constante qu'on met dans le .h, et si jamais il y une autre tentative d'inclusion, grâce à la condition l'entete ne sera pas de nouveau incluse vu que la constante aura été définie a la premiere inclusion."
Exactement
"Mais on utilise un espace memoire pour rien non a definir une constante comme ça ?"
Non, ce nom est reservé au moment de la compilation, mais disparait dans le code binaire.
ok merci
"Non, ce nom est reservé au moment de la compilation, mais disparait dans le code binaire."
Et c'est pour ça qu'il y a des underscore devant le nom. Car la norme du C dit que mis à part les fonctions qu'elle décrit, un fichier d'en tête standard n'a pas le droit de définir quoi que ce soit d'autre, sauf si ça commence par un underscore.
zut ... saleté de norme, ça va m'en faire des fichier a éditer ![]()
pourtant ca passe sans undescore, c'est vrmt nimp. Tout les compilos devraient etre reglés pour la norme.....
faut juste que ca commence par _ ? et à la fin yen faut aussi un?
et cest le _ qui fait que ca disparait dans le binaire ?
par "norme", dnob voulait juste parler de regle d'implémentation, ou plutot de convention si tu preferes.
Mais le compilo l'acceptera bien sur.
C'est juste une convention.
Tout comme les déclarations de variable devraient apparaitre au début de leur portée.
Enfin bon...
Et non, ce n'est pas le "_", qui fait que ce n'est pas dans le binaire, mais le fait que c'est une définition par macro.
Une macro si tu veux, elle est analysée lors de la compilation, mais rien n'est traduit dans le .exe
Donc c'est juste un "repère" pour le compilateur.
- Quand le compilo va "lire" #ifndef _machin il va se dire : "machin est défini ?" non -> alors je continue
- et il va lire "#define _machin" donc hop, machin est défini,
- et puis il va lire le contenu du header.
Donc c'est vraiment quelque chose qui n'est "calculé" qu'à la compilation.
Exactement comme si je fais :
et bien si dans mon code je me sers de PI, lors de la compilation, le compilo va remplacer PI par la valeur, mais c'est vraiment de la substitution hein.
Donc au final la constante n'existera jamais en mémoire, au niveau de ton programme.
Dans ton .exe, seuls des 3.14 seront présents
j'espère avoir réussi à t'éclairer.
Bonne soirée
non, par norme, je voulais vraiment dire norme.
La norme dit que pour qu'un compilo soit déclaré standard, il ne faut pas que sa bibliothèque déclare des symbole ne commançant pas par un underscore (entre autre) autre que ceux définie par la norme.
Mais bien sûr, rien n'empêche un programmeur de définir ce qu'il vaut. Seulement si gcc était distribué directement avec des en têtes où les macro ne débute pas par des underscore, il serait déclaré non conforme (dans la mesure où il l'est). Quelqu'un qui écrit sa propre bibliothèque fait ce qu'il vaut.
De même pour la déclaration des variables au début de leur bloc (et non pas de leur porté). C'est aussi la norme (du C89 seulement). Mais les compilos modernes sont "gentils" avec le programmeur et par défaut, il ne vont pas interdire tout ce qui est interdit par la norme (au contraire, il ont tendance a accepter beaucoup plus de choses).
Mais avec gcc par exemple on peut forcer un comportement standard (pas exactement, mais le reste est une question de détail) en compilant avec les options "-std=c89 -ansi -pedantic-error" et là, des variables ne peuvent plus être déclarées après du code (par contre, on peut toujours mettre les macros que l'on veut dans un en tête, ça c'est autorisé, sauf pour la bibliothèque standard).
"zut ... saleté de norme, ça va m'en faire des fichier a éditer"
guyver : pour préciser la fin de mon dernier message, si je ne suis pas clair, c'est que tu n'a pas besoin de changer quoi que ce soit. Ce point de la norme ne concerne que la bibliothèque standard.
Néanmoins, il est conseillé pour les autres bibliothèque de le suivre aussi. Mais là, comme dit saleGauss, c'est une convention.
d'accord dnob, on ne s'était pas compris, je croyais que tu parlais sur les hearders en général.
Désolé, autant pour moi !
Bonne soirée
saleGauss => merci c 'est très clair ![]()
J'ai la source d'un programme ya un seul fichier cpp et beaucoup de .h mais dans les .h Il y a carrément le corps des fonctions et tout. On doit pas mettre que les profils des fonctions sans le corps normalement ?
c'est "juste" une norme.
la déclaration de fonctions dans un .h peut poser problème dans le cas de multiples inclusions. C'est assez crade comme méthode mais si tu sais ce que tu fait, le C te permet d'ecrire un peu tout et n'importe quoi (et surtout n'importe comment).
En plus d'être crade, ça peut te faire perdre pas mal de temps à la compilation sur de gros projets, tu changes un truc dans une fonction du .h, et tout les fichiers qui incluent le .h devront être recompilés à la prochaine compilation du projet.