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

Bonne pratique concernant les en-têtes

12 réponses
Avatar
Thoma
Bonjour,

Eternelle d=E9butant, je cherche =E0 savoir lequel des deux cas ci-dessous
est =E0 pr=E9f=E9rer et pourquoi ?

Cas 1:
----------------------------------- file1.h
------------------------------------
#ifndef __FILE1_H__
#define __FILE1_H__

typedef struct container
{
struct container * prev;
struct container * next;
content * ptr;
} container;

#endif /* __FILE1_H__ */
----------------------------------- file2.h
------------------------------------
#ifndef __FILE2_H__
#define __FILE2_H__

typedef
{
size_t size;
void * ptr;
} content;

#endif /* __FILE2_H__ */
---------------------------------- example.c
-----------------------------------
#include "file2.h"
#include "file1.h"

int main(int argc, char * argv[])
{
...
}

Cas 2:
----------------------------------- file1.h
------------------------------------
#ifndef __FILE1_H__
#define __FILE1_H__

#include "file2.h"

typedef struct container
{
struct container * prev;
struct container * next;
content * ptr;
} container;

#endif /* __FILE1_H__ */
----------------------------------- file2.h
------------------------------------
#ifndef __FILE2_H__
#define __FILE2_H__

typedef
{
size_t size;
void * ptr;
} content;

#endif /* __FILE2_H__ */
---------------------------------- example.c
-----------------------------------
#include "file1.h"

int main(int argc, char * argv[])
{
...
}

En d'autres termes, dans un projet d=92envergure, doit-on minimiser le
nombre d=92appel =E0 des fichiers d=92en-t=EAte dans les fichiers d=92en-t=
=EAtes
(et ce sont les d=E9veloppeurs qui sont responsable de l=92ordre d=92appel
des fichiers d=92en-t=EAte) ? Ou bien, g=E9rer les d=E9pendances entre
fichiers d=92en-t=EAte (et minimiser le nombre d=92appel =E0 des fichiers d=
=92en-
t=EAte dans les fichiers sources) ?

D'avance merci

Thoma

10 réponses

1 2
Avatar
Pierre Maurette
Thoma, le 15/09/2009 a écrit :

[...](j'ai tout coupé parce qu'il y a des caractères qui ne passent
pas)

Ce que j'ai retenu c'est que chaque fichier doit être autonome quant à
ses #include. Donc #include-r tout ce qu'il faut et juste ce qu'il
faut. C'est donc la proposition "Cas 2" que je choisirais. Attention,
si on utilise directement content dans example.c, je suis pour y
ajouter un #include "file2.h".


--
Pierre Maurette
Avatar
Wykaaa
Thoma a écrit :
Bonjour,




[couic]

En d'autres termes, dans un projet d’envergure, doit-on minimiser le
nombre d’appel à des fichiers d’en-tête dans les fichiers d’en-têtes
(et ce sont les développeurs qui sont responsable de l’ordre d’appel
des fichiers d’en-tête) ? Ou bien, gérer les dépendances entre
fichiers d’en-tête (et minimiser le nombre d’appel à des fichiers d’en-
tête dans les fichiers sources) ?

D'avance merci

Thoma



Si l'on a une approche objet, les .h représentent les classes (en C : un
objet avec sa structure + les prototypes des fonctions qui concernent
cette structure).
Les dépendances entre fichiers d'en-tête correspondent donc aux
dépendances entre objets telles qu'identifiées lors de la conception
globale.

Je ne vois d'ailleurs pas de prototype de fonctions dans tes fichiers
d'en-tête. Où sont-ils ?
Avatar
-ed-
On 15 sep, 14:54, Thoma wrote:

Cas 2:
----------------------------------- file1.h
------------------------------------
#ifndef __FILE1_H__
#define __FILE1_H__

#include "file2.h"

typedef struct container
{
  struct container * prev;
  struct container * next;
  content          * ptr;

}
container; /* -ed- ajouté */
#endif /* __FILE1_H__ */
----------------------------------- file2.h
------------------------------------
#ifndef __FILE2_H__
#define __FILE2_H__

typedef
{
  size_t size;
  void   * ptr;

} content;

#endif /* __FILE2_H__ */
---------------------------------- example.c
-----------------------------------
#include "file1.h"

int main(int argc, char * argv[])
{
  ...

}

En d'autres termes, dans un projet d’envergure, doit-on minimiser le
nombre d’appel à des fichiers d’en-tête dans les fichiers d’en- têtes



on doit faire ce qu'il faut pour que le code soit simple à coder et à
utiliser.

(et ce sont les développeurs qui sont responsable de l’ordre d’appe l
des fichiers d’en-tête) ? Ou bien, gérer les dépendances entre
fichiers d’en-tête (et minimiser le nombre d’appel à des fichiers d’en-
tête dans les fichiers sources) ?



Le deuxième cas est à préférer, car il y a une dépendance
( 'container' dépend de 'content' ) . Celle ci- est réglée
automatiquement par le deuxième cas. L'utilisateur n'a qu'un seul
fichier d'entête à gérer.

Attention, si ce code est applicatif, il est incorrect. Le langage C
attribue les identificateurs commençant par _ à l'implémentation. Je
suggère :

#ifndef H_FILE1
#define H_FILE1

http://www.bien-programmer.fr/codage.php#organiser_source
http://www.bien-programmer.fr/codage.php#organiser
Avatar
Thoma
On 15 sep, 20:01, -ed- wrote:
On 15 sep, 14:54, Thoma wrote:





> Cas 2:
> ----------------------------------- file1.h
> ------------------------------------
> #ifndef __FILE1_H__
> #define __FILE1_H__

> #include "file2.h"

> typedef struct container
> {
>   struct container * prev;
>   struct container * next;
>   content          * ptr;

> }
> container; /* -ed- ajouté */
> #endif /* __FILE1_H__ */
> ----------------------------------- file2.h
> ------------------------------------
> #ifndef __FILE2_H__
> #define __FILE2_H__

> typedef
> {
>   size_t size;
>   void   * ptr;

> } content;

> #endif /* __FILE2_H__ */
> ---------------------------------- example.c
> -----------------------------------
> #include "file1.h"

> int main(int argc, char * argv[])
> {
>   ...

> }

> En d'autres termes, dans un projet d’envergure, doit-on minimiser le
> nombre d’appel à des fichiers d’en-tête dans les fichiers d’e n-têtes

on doit faire ce qu'il faut pour que le code soit simple à coder et à
utiliser.

> (et ce sont les développeurs qui sont responsable de l’ordre d’ap pel
> des fichiers d’en-tête) ? Ou bien, gérer les dépendances entre
> fichiers d’en-tête (et minimiser le nombre d’appel à des fichie rs d’en-
> tête dans les fichiers sources) ?

Le deuxième cas est à préférer, car il y a une dépendance
( 'container' dépend de 'content' ) . Celle ci- est réglée
automatiquement par le deuxième cas. L'utilisateur n'a qu'un seul
fichier d'entête à gérer.

Attention, si ce code est applicatif, il est incorrect. Le langage C
attribue les identificateurs commençant par _ à l'implémentation. J e
suggère :

#ifndef H_FILE1
#define H_FILE1

http://www.bien-programmer.fr/codage.php#organiser_sourcehttp://www.bien- programmer.fr/codage.php#organiser- Masquer le texte des messages précé dents -

- Afficher le texte des messages précédents -



Bonjour,

Avant tout, merci à vous d'avoir passer du temps sur cette question.

-> Pierre MAURETTE
Je suis d'accord avec vous concernant l'inclusion de "file2.h" si l'on
utilise 'content'.

-> Wykaaa
L'exemple n'est pas complet et ne soulève que la problématique des
dépendances entre fichiers d'en-tête d'où l'absence des prototypes de
fonction.

-> -ed-
Effectivement, j'ai encore de vieilles habitudes à gommer concernant
le choix des identificateurs.
J'avais déjà trainer sur le lien que vous proposez.

Si d'autres personnes pouvez infirmer ou confirmer ces avis?

D'avance merci

Thoma
Avatar
Wykaaa
Thoma a écrit :

[couic]

-> -ed-
Effectivement, j'ai encore de vieilles habitudes à gommer concernant
le choix des identificateurs.
J'avais déjà trainer sur le lien que vous proposez.

Si d'autres personnes pouvez infirmer ou confirmer ces avis?

D'avance merci

Thoma



Ce n'est pas le langage C qui impose quoi que ce soit concernant les
identificateurs commençant pas _ mais la "coutume".
Dans Unix, la "coutume" veut que les variables système commencent par _
Une application ne devrait donc jamais utiliser de variables dont le nom
commence par ce caractère.
Avatar
espie
In article <4ab09ace$0$17738$,
Wykaaa wrote:
Thoma a écrit :

[couic]

-> -ed-
Effectivement, j'ai encore de vieilles habitudes à gommer concernant
le choix des identificateurs.
J'avais déjà trainer sur le lien que vous proposez.

Si d'autres personnes pouvez infirmer ou confirmer ces avis?

D'avance merci





Thoma





Ce n'est pas le langage C qui impose quoi que ce soit concernant les
identificateurs commençant pas _ mais la "coutume".
Dans Unix, la "coutume" veut que les variables système commencent par _
Une application ne devrait donc jamais utiliser de variables dont le nom
commence par ce caractère.



La formulation est hasardeuse, on pourrait presque lui faire dire le
contraire de ce que tu as dis.

C'est quoi "le langage C" ? Il y a:
- des compilateurs
- des systemes
- une norme.

Tu melanges sauvagement les trois...

La norme stipule clairement que les identifiants commencant par _ sont
*reserves pour l'implementation* (je laisse de cote les details,
l'idee est la).

En terme de "coutumes", ca veut juste dire que, si tu outrepasses cette
specification, tu risques les collisions avec les details internes de
l'implementation, que ce soit ton compilo, ou le reste du systeme:
si ton programme continue a marcher, c'est par accident, car tu n'as plus
aucune garantie que tu n'entres pas en conflit, de maniere
plus ou moins sournoise, avec des details internes de ton compilateur, ou
de ton systeme.

Meme pour le systeme, il faut quand meme faire gaffe:
a chaque fois que tu changes de compilateur, tu t'exposes
a des soucis supplementaires, la separation n'est pas tres nette !

Me suis deja tape quelques migrations de versions de gcc, avec toutes
les joies que ca occasionne...
Avatar
-ed-
On 16 sep, 09:59, Wykaaa wrote:
Ce n'est pas le langage C qui impose quoi que ce soit concernant les
identificateurs commençant pas _ mais la "coutume".



Bah non. C'est bien défini dans le langage C. L'usage des
identificateurs commençant par _ est réservé à l"implémentation.

Je te laisse vérifier :

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Dans Unix, la "coutume" veut que les variables système commencent par _
Une application ne devrait donc jamais utiliser de variables dont le nom
commence par ce caractère.



Y' pas que dans Unix. C'est imposé par le langage...
Avatar
Wykaaa
Marc Espie a écrit :
In article <4ab09ace$0$17738$,
Wykaaa wrote:
Thoma a écrit :

[couic]

-> -ed-
Effectivement, j'ai encore de vieilles habitudes à gommer concernant
le choix des identificateurs.
J'avais déjà trainer sur le lien que vous proposez.

Si d'autres personnes pouvez infirmer ou confirmer ces avis?

D'avance merci





Thoma





Ce n'est pas le langage C qui impose quoi que ce soit concernant les
identificateurs commençant pas _ mais la "coutume".
Dans Unix, la "coutume" veut que les variables système commencent par _
Une application ne devrait donc jamais utiliser de variables dont le nom
commence par ce caractère.



La formulation est hasardeuse, on pourrait presque lui faire dire le
contraire de ce que tu as dis.

C'est quoi "le langage C" ? Il y a:
- des compilateurs
- des systemes
- une norme.

Tu melanges sauvagement les trois...

La norme stipule clairement que les identifiants commencant par _ sont
*reserves pour l'implementation* (je laisse de cote les details,
l'idee est la).

En terme de "coutumes", ca veut juste dire que, si tu outrepasses cette
specification, tu risques les collisions avec les details internes de
l'implementation, que ce soit ton compilo, ou le reste du systeme:
si ton programme continue a marcher, c'est par accident, car tu n'as plus
aucune garantie que tu n'entres pas en conflit, de maniere
plus ou moins sournoise, avec des details internes de ton compilateur, ou
de ton systeme.

Meme pour le systeme, il faut quand meme faire gaffe:
a chaque fois que tu changes de compilateur, tu t'exposes
a des soucis supplementaires, la separation n'est pas tres nette !

Me suis deja tape quelques migrations de versions de gcc, avec toutes
les joies que ca occasionne...



OK. Je suis d'accord que j'ai fait un "raccourci". D'un autre côté
"réservé à l'implémentation" n'est pas complètement clair non plus. Ceci
dit, on sent bien qu'il faut se méfier...
Avatar
Wykaaa
-ed- a écrit :
On 16 sep, 09:59, Wykaaa wrote:
Ce n'est pas le langage C qui impose quoi que ce soit concernant les
identificateurs commençant pas _ mais la "coutume".



Bah non. C'est bien défini dans le langage C. L'usage des
identificateurs commençant par _ est réservé à l"implémentation.

Je te laisse vérifier :

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Dans Unix, la "coutume" veut que les variables système commencent par _
Une application ne devrait donc jamais utiliser de variables dont le nom
commence par ce caractère.



Y' pas que dans Unix. C'est imposé par le langage...



Alors voici ce que dit le document que tu cites en référence (qui n'est
qu'un draft de la norme) et c'est une note de bas de page (§ 7.1.4, page
167 :

163) Because external identifiers and some macro names beginning with an
underscore are reserved, implementations may provide special semantics
for such names. For example, the identifier _BUILTIN_abs could be used
to indicate generation of in-line code for the abs function.

Il faut savoir lire : il y a une virgule entre reserved et implementations.
Et la fin de la phrase dit (c'est moi qui souligne):
implementations _may_ provide special semantics for such names

Dans ce même document, il est dit (§6.4.2.1, page 51) :
An identifier is a sequence of nondigit characters (including the
underscore _, the lowercase and uppercase Latin letters, and other
characters) and digits,

Donc ce que dit la norme entérine le fait que c'était une coutume de
commencer les identificateurs "système" par un _

Elle n'impose rien du tout (puisque c'est autorisé dans le langage, un
compilateur ne fera pas de vérification) mais c'est à tes risques et
périls...
Avatar
Richard Delorme
Le 16/09/2009 12:49, Wykaaa a écrit :

Alors voici ce que dit le document que tu cites en référence (qui n'est
qu'un draft de la norme) et c'est une note de bas de page (§ 7.1.4, page
167 :



Le bon paragraphe est le 7.1.3 :
[...]
— All identifiers that begin with an underscore and either an uppercase
letter or another underscore are always reserved for any use.
— All identifiers that begin with an underscore are always reserved for
use as identifiers with file scope in both the ordinary and tag name spaces.

Elle n'impose rien du tout (puisque c'est autorisé dans le langage, un
compilateur ne fera pas de vérification) mais c'est à tes risques et
périls...



Si :
[...]If the program declares or defines an identifier in a
context in which it is reserved (other than as allowed by 7.1.4), or
defines a reserved identifier as a macro name, the behavior is undefined.

--
Richard
1 2