Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

pas de #include dans un fichier d'en-tête ?

34 réponses
Avatar
gregg
Bonsoir,

Un professeur de faculté a "assassiné" mon code sous prétexte qu'on n'a
pas le droit "d'inclure un .h dans un .h".
(Il ne s'agit pas de <stdio.h>, mais de "xxx.h" personnels)

J'avoue que ça me choque un peu (j'ai appris le C en compulsant les
sources de FreeBSD, et accessoirement de la bibliothèque standard, et
cette façon de faire ne semble pas gêner)

Je ne vois pas vraiment d'argument contre une telle pratique.
Il ne risque pas d'y avoir inclusions multiples, ou récursives,
puisqu'il y a des gardes-fous ( #ifndef machin #define machin #endif)

Ca me paraît même plus dans l'esprit "déclaration de services".

J'ai lu la faq, mais cet aspect n'apparaît pas.
Enfin: quelle est votre pratique personnelle ?

10 réponses

1 2 3 4
Avatar
Antoine Leca
En , Yves ROMAN va escriure:
<Paléontologie>
Est-ce qu'à une époque cette limitation n'aurait pas existé sur les
(pré)compilateurs : imossibilité de traiter un #include dans un
#include ? </Paléontologie>


Après vérification, c'est bien possible que ce fut limité.
Les #include viennent de Unix V4 (1973). Le préprocesseur (substitution des
macros) était alors traité directement par cc. Pour que le préprocesseur
soit lancé, il fallait que le tout premier caractère du source soit un #
(c'est de là que vient la directive # seule de la norme ANSI...) C'était le
genre d'économie propre de l'époque...

Les sources du compilo de V4 ont disparus. Ceux de V5, comme ceux de V6,
montrent qu'il n'était pas possible d'avoir un #include à l'intérieur d'un
#include. Le tutorial du compilateur (écrit par M. Kernighan, et disponible
sur la page de M. Ritchie) explique bien clairement cette limitation.

Depuis 1979 ("nouveau" cpp de John Reiser, inclut dans V7), cela n'a plus
cours (au moins 9 includes emboîtés).


Antoine

Avatar
Yves ROMAN

En , Yves ROMAN va escriure:
<Paléontologie>
Est-ce qu'à une époque cette limitation n'aurait pas existé sur les
(pré)compilateurs : imossibilité de traiter un #include dans un
#include ? </Paléontologie>


[...]


Depuis 1979 ("nouveau" cpp de John Reiser, inclut dans V7), cela n'a plus
cours (au moins 9 includes emboîtés).



- Existe-t-il une limitation dans la norme sur le nombre d'inclusion enboîtées ?

Parce-qu'en mettant des #include dans des includes, on ne sait plus à quel
niveau d'imbrication on est. (C'est encore plus vrai en C++ avec beaucoup
d'héritage et le #include de la classe mère dans l'include de la classe fille)

- Dans le même genre d'idée, y a-t-il une limitation sur le niveai d'mbrication
des #define ?

Je me souviens d'un problème sous VAX/VMS ou le préprocesseur craquait à cause
d'une longue série de :
#define A0 1000
#define A1 (A0+1)
#define A2 (A1+1)
#define A3 (A2+1)
etc...
(Qu'il avait suffit de changer en
#define A2 (A0+2)
#define A3 (A0+3)
etc...


Avatar
Antoine Leca
En , Yves ROMAN va escriure:
Depuis 1979 ("nouveau" cpp de John Reiser, inclut dans V7), cela n'a
plus cours (au moins 9 includes emboîtés).


- Existe-t-il une limitation dans la norme sur le nombre d'inclusion
enboîtées ?


Oui, au moins 8 niveaux en C90 et 15 niveaux en C99.
(Donc le préprocesseur de M. Reiser ne passe pas la norme C99 ;-))


- Dans le même genre d'idée, y a-t-il une limitation sur le niveai
d'mbrication des #define ?


Nombre de #define: au moins 1024 en C90, 4095 en C99.
Nombre de #if (ou #ifdef etc.) emboîtés: au moins 8 en C90, au moins 63 en
C99.

Comme on peut le voir, C99 a sensiblement remonté la barre à ce niveau.

De toute manière, la norme prescrit d'éviter d'avoir la moindre limitation.


Antoine


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', AG wrote:

En clair, les gardes (#ifndef, #define, #endif) comme indiqué par la
faq. Et inclusion dans les .h si le service proposé par le .h le
demande, sinon dans le.c ?
Bon ben comme tout le monde l'a déjà dit, oui. Cela dit, va pas inclure

un .h dans une en-tête standard (genre stdio.h). Parce que là, c'est pas
bien.


Certes, il ne faut pas modifier les entêtes de son compilateur. Chez moi, ils
sont en read-only, ça évite les tentations...

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Avatar
Alexandre BACQUART
Stephane Legras-Decussy wrote:
"Alexandre BACQUART" a écrit dans le message de news:
407079bb$0$12802

void main() {printf("Free The World !");} /* copyleft */



int main() ....




Certes :)

--
Tek
int main() {printf("Free The World !");} /* copyleft */


Avatar
Régis Troadec
"gregg" a écrit dans le message de
news:407038f0$0$31085$
Bonsoir,


Salut,

Un professeur de faculté a "assassiné" mon code sous prétexte qu'on n'a
pas le droit "d'inclure un .h dans un .h".
(Il ne s'agit pas de <stdio.h>, mais de "xxx.h" personnels)


Allez, allez, en le faisant parler il te lachera surement des raisons
valables, au moins son point de vue sur le sujet :), il sera plus precis et
le "on n'a pas le droit" se transformera peut-etre en "je pense que ce n'est
pas une bonne pratique parce que...ceci...cela...etc..."
S'il n'en est pas capable, c'est la que ce n'est pas un bon prof. J'ai
toujours bassine mes profs de langage C et obtenu satisfaction la plupart du
temps.

J'ai lu la faq, mais cet aspect n'apparaît pas.


Si tu as le courage de lire de l'anglais (toute de meme tres abordable), il
a les FAQs de c.l.c, le sujet est traité au point 10.7 :
http://www.eskimo.com/~scs/C-faq/q10.7.html

Regis

Avatar
Alexandre BACQUART
Emmanuel Delahaye wrote:

In 'fr.comp.lang.c', AG wrote:


En clair, les gardes (#ifndef, #define, #endif) comme indiqué par la
faq. Et inclusion dans les .h si le service proposé par le .h le
demande, sinon dans le.c ?


Bon ben comme tout le monde l'a déjà dit, oui. Cela dit, va pas inclure
un .h dans une en-tête standard (genre stdio.h). Parce que là, c'est pas
bien.



Certes, il ne faut pas modifier les entêtes de son compilateur. Chez moi, ils
sont en read-only, ça évite les tentations...


Enfin les erreurs plutôt, car je trouve que la simple tentation de
modifier un en-tête standard est une hérésie.

--
Tek
int main() {printf("Free The World !");} /* copyleft */



Avatar
Antoine Leca
En 4071da7c$0$19572$, Alexandre BACQUART va escriure:
Certes, il ne faut pas modifier les entêtes de son compilateur. Chez
moi, ils sont en read-only, ça évite les tentations...


Enfin les erreurs plutôt, car je trouve que la simple tentation de
modifier un en-tête standard est une hérésie.


Bizarre ; les seules fois où j'ai modifié les entêtes d'une implémentation
(en dehors bien sûr des fois où c'est moi qui les écrit), c'était pour
corriger les erreurs *dedans*... (en particulier avec les far, _cdecl, et
autres joyeusetés non normalisées).


Antoine


Avatar
DINH Viêt Hoà

Bizarre ; les seules fois où j'ai modifié les entêtes d'une implémentation
(en dehors bien sûr des fois où c'est moi qui les écrit), c'était pour
corriger les erreurs *dedans*... (en particulier avec les far, _cdecl, et
autres joyeusetés non normalisées).


vaut mieux pas workarounder les problèmes plutôt que modifier les
en-têtes afin d'avoir à refaire la chose sur toutes les machines sur
lesquelles tu vas compiler le code ?

--
DINH V. Hoa,

"on dirait un gamin de 2 ans" -- coin-coin

Avatar
DINH Viêt Hoà
int main(void) { printf("Free The World !n"); } /* copyleft */

--
DINH V. Hoa,

"on dirait un gamin de 2 ans" -- coin-coin
1 2 3 4