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
Éric Lévénez
Le 4/04/04 23:06, dans <407078ca$0$14539$, « gregg »
a écrit :

( j'ai constaté qu'il prenait le contre-pieds de la plupart des usages
recommandés, entre autres, par les contributeurs de ce forum, comme par
exemple utiliser des "return" partout dans la fonction plutôt que
d'utiliser une variable et un unique point de sortie, ou des écritures
très condensées, à la limite de la lisibilité).


Je trouve qu'il est plus clair avoir plusieurs return si la fonction est
simple et n'a pas besoin de code spécifique avant le return. Par exemple :

int code(int val)
{
if (val < 1)
return 1;
if (val > 42)
return 2;
if (val % 2)
return 3;
return -1;
}

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Yves ROMAN

gregg wrote:
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".



Ton prof est certainement un névrosé de la récursivité dont le coté
tranchant à fait souffrir beaucoup de gens :)



Peut-être a-t-il été marqué dans sa jeunesse quand il a dû faire à la main un
makefile d'un projet et rechercher de quels #$@%§ de .h pouvait bien dépendre un
.c ...


Avatar
AG
gregg 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.

Alexandre.

Avatar
DINH Viêt Hoà

Ton prof est certainement un névrosé de la récursivité dont le coté
tranchant à fait souffrir beaucoup de gens :)


Peut-être a-t-il été marqué dans sa jeunesse quand il a dû faire à la main un
makefile d'un projet et rechercher de quels #$@%§ de .h pouvait bien dépendre un
.c ...


dans le monde moderne, il existe des outils qui affichent ces
dépendances (gcc -jenesaisquelleoption).

--
DINH V. Hoa,

"écrire 'dsl' au lieu de 'désolé', c'est pas un problème d'orthographe,
c'est un problème de capillarité palmaire" -- ed


Avatar
Yves ROMAN

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".


<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>

Avatar
Richard Delorme


Ton prof est certainement un névrosé de la récursivité dont le coté
tranchant à fait souffrir beaucoup de gens :)


Peut-être a-t-il été marqué dans sa jeunesse quand il a dû faire à la main un
makefile d'un projet et rechercher de quels #$@%§ de .h pouvait bien dépendre un
.c ...


dans le monde moderne, il existe des outils qui affichent ces
dépendances (gcc -jenesaisquelleoption).


gcc -M ou gcc -MM
Cela dit c'est spécifique à gcc et la disponibilité d'une fonction
équivalente n'est pas sûre. Ni susv2 ("vieille" norme unix avec C89), ni
susv3 (norme Unix avec c99), ne requiert cette option par exemple.

--
Richard



Avatar
Antoine Leca
En 407038f0$0$31085$, gregg va escriure:
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)


On « a le droit ».

Certaines règles de programmation peuvent demander à ne jamais #inclure de
.h personnels à l'intérieur des .h.


J'avoue que ça me choque un peu


« Choquant » ? Plus le « assassiné » ci-dessus, cetes entre guillemets, tu
ne crois pas que tu utilises un vocabulaire un peu emphatique ? Que t'as
dis exactement ton professeur (et dans quel contexte) ? Est-ce qu'il a noté
ton projet, par ailleurs parfait (!), à 6/20, avec comme unique raison « il
est interdit d'inclure un .h dans un .h » ? (ce serait effectivement
choquant). Ou est-ce que c'est plus nuancé ?

Une autre bonne question, c'est ce qu'il a dit en cours sur le sujet... Cela
m'est arrivé plus d'une fois de me faire mal noté pour avoir enfreint une
règle jugée importante par un professeur, mais par ailleurs « inutile »,
règle dont j'ignorais l'existence pour avoir sèché le dit cours ! J'ai même
parfois soupçonné certains professeurs de le faire exprès, pour donner une
« prime » à ceux qui faisaient l'effort d'aller en cours, ce qui est
parfaitement raisonnable, ÀMHA.


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)


C'est seulement une toute petite partie du problème.

Les entêtes signalent les composants (modules) utilisés. Le principe, c'est
l'encapsulation, utiliser un composant signifie utiliser uniquement son .h,
sans se préoccuper le moins du monde de ce dont l'implémentation de ce
composant a réellement besoin. Les deux idées ici sont:

- d'un côté (le tien), « le programmeur est responsable ». Le .h fourni
fait « ce qu'il faut », on a pas à regarder dedans (à la limite), donc je
peux faire ce dont j'ai envie, y compris déclarer des variables, des
fonctions, des macros, ou #inclure d'autres entêtes, à condition que l'effet
sur le code du client soit nul (limitation évidente, en C sans les
namespaces, il faut de la documentation pour réserver une partie de l'espace
de noms pour les objets que l'on déclare)

- de l'autre, « il faut un contrôle ». Le .h fourni ne déclare que ce qui
est prévu de déclarer, rien d'autres. (Corrolaire, l'implémentation du
module va avoir probablement un autre .h pour ses propres éléments
d'entêtes). De ce fait, un vérificateur du code n'a pas besoin d'aller
chercher le contenu du .h pour savoir ce qu'il fait, ce qui simplifie son
boulot. Dans le même genre de règles, on a la liste des #include au début du
programme principal qui donne directement la liste complète des composants
utilisés (même s'ils sont inutiles dans ce programme-là).


Enfin: quelle est votre pratique personnelle ?


Les deux. Y compris les règles de programmation l'obligeant, dans un sens
comme dans l'autre.
Tout ceci pour dire que cela dépend du contexte!


Antoine

Avatar
Antoine Leca
En 40710c17$0$14174$, Alexandre va escriure:
Cela dit, va pas
inclure un .h dans une en-tête standard (genre stdio.h).


Et comment tu peux faire cela ?

Ou vu de l'autre côté (celui de l'implémenteur): bien sûr que si !


Antoine

Avatar
Antoine Leca
En , DINH Viêt Hoà va escriure:
dans le monde moderne, il existe des outils qui affichent ces
dépendances (gcc -jenesaisquelleoption).


cpp -M
cpp -MM


Antoine

Avatar
AG
Antoine Leca wrote:
Et comment tu peux faire cela ?
Monsieur Leca, vous avez parfaitement compris. Il suffit pour cela d'éditer

stdio.h, et d'y mettre, au début, #include <monfichier.h>. Il y a des gens qui
sont capables de faire ça (et je ne pense pas à l'OP en disant ça).


Ou vu de l'autre côté (celui de l'implémenteur): bien sûr que si !
C'est bien parce que certains on l'esprit mal tourné comme ça que je trouvais

cette précision utile...

Alexandre.

1 2 3 4