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

bibliotheque et fichiers d'en-tete pour l'utilisateur

50 réponses
Avatar
Vincent Lefevre
Bonjour et bonne année,

J'aimerais avoir votre avis sur le point suivant (je n'ai pas vu
d'indications dans les FAQ). Dans la bibliothèque qu'on développe
(MPFR), il y a des fonctions qui ne sont liées aucunement à la
bibliothèque standard et d'autres qui sont liées à certaines choses
de <stdio.h> (par exemple utilisent FILE en argument, parce que ce
sont des fonctions d'entrées/sorties). Y a-t-il une ou des solutions
recommandées concernant les fichiers d'en-tête fournis par la
bibliothèque (pour l'utilisateur de la bibliothèque), avec une
volonté de portabilité?

1) La solution actuelle est celle de GMP, qui est d'essayer de
détecter automatiquement si <stdio.h> a été #inclus avant gmp.h,
auquel cas gmp.h déclare les fonctions d'entrées/sorties. Mais cela
pose notamment deux gros problèmes: comme il n'y a pas de standard
pour cette détection, cela risque d'échouer sur les plateformes non
testées (et cela arrive en pratique) ou à cause de changements futurs
sur les plateformes existantes (cf tous les problèmes qu'a posés le
changement lié au errno dans la glibc); d'autre part, cette méthode
empiète sur le domaine de l'utilisateur. Par exemple, le programme
suivant ne compile pas:

#define H_STDIO 1
#include <gmp.h>

int main(void)
{
return 0;
}

(à noter que H_STDIO ne fait pas partie des macros réservées par GMP,
qui commencent par "GMP_", par convention).

2) Il y a la solution d'inclure systématiquement <stdio.h> dans le
fichier d'en-tête qu'on fournit (mpfr.h), éventuellement sauf si telle
macro, e.g. MPFR_NO_STDIO, est définie auparavant par l'utilisateur
(évidemment, tout cela devant être parfaitement documenté...).

3) Il y a la solution de fournir plusieurs fichiers d'en-tête, e.g.
mpfr.h et mpfrIO.h, où <stdio.h> n'est inclus que dans "mpfrIO.h".
C'est une sorte de (2) modulaire.

Dans les quelques bibliothèques que j'ai regardées (à part GMP), c'est
soit (2) sans la possibilité d'empêcher l'inclusion, soit (3).

Pour info, ma préférence personnelle va pour (3), pour son aspect
modulaire en particulier.

--
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

10 réponses

1 2 3 4 5
Avatar
Gabriel Dos Reis
writes:

|
| > C'est pour te proteger
| > contre un entete mal foutu qui ne gere pas les inclusions multiples ?
|
| précisemment.

Dans ce cas, la solution n'a jamais été de faire encore plus mal foutu.

-- Gaby
Avatar
Vincent Lefevre
Dans l'article <bten8n$6av7m$,
Bertrand Mollinier Toublet écrit:

Ca doit etre le manque d'experience, mais je n'ai jamais ressenti le
besoin de *ne pas* include un fichier d'entete. C'est pour te proteger
contre un entete mal foutu qui ne gere pas les inclusions multiples ?


Je pense que ce serait plutôt pour les programmeurs qui n'en veulent
pas, pour des applications spécifiques (comme l'implémentation d'une
bibliothèque standard ou des choses de ce niveau).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:

| Dans l'article <bten8n$6av7m$,
| Bertrand Mollinier Toublet écrit:
|
| > Ca doit etre le manque d'experience, mais je n'ai jamais ressenti le
| > besoin de *ne pas* include un fichier d'entete. C'est pour te proteger
| > contre un entete mal foutu qui ne gere pas les inclusions multiples ?
|
| Je pense que ce serait plutôt pour les programmeurs qui n'en veulent
| pas, pour des applications spécifiques (comme l'implémentation d'une
| bibliothèque standard ou des choses de ce niveau).

Une implémentation d'une bibliothèque standard n'est jamais construite
de cette manière là -- autrement, elle est sérieusement bugguée.

-- Gaby
Avatar
Vincent Lefevre
Dans l'article ,
Gabriel Dos Reis écrit:

Vincent Lefevre <vincent+ writes:

| Dans l'article <bten8n$6av7m$,
| Bertrand Mollinier Toublet écrit:
|
| > Ca doit etre le manque d'experience, mais je n'ai jamais ressenti le
| > besoin de *ne pas* include un fichier d'entete. C'est pour te proteger
| > contre un entete mal foutu qui ne gere pas les inclusions multiples ?
|
| Je pense que ce serait plutôt pour les programmeurs qui n'en veulent
| pas, pour des applications spécifiques (comme l'implémentation d'une
| bibliothèque standard ou des choses de ce niveau).

Une implémentation d'une bibliothèque standard n'est jamais construite
de cette manière là -- autrement, elle est sérieusement bugguée.


OK. Sinon, qu'en est-il des implémentations freestanding?

--
Vincent Lefèvre - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:

| Dans l'article ,
| Gabriel Dos Reis écrit:
|
| > Vincent Lefevre <vincent+ writes:
|
| > | Dans l'article <bten8n$6av7m$,
| > | Bertrand Mollinier Toublet écrit:
| > |
| > | > Ca doit etre le manque d'experience, mais je n'ai jamais ressenti le
| > | > besoin de *ne pas* include un fichier d'entete. C'est pour te proteger
| > | > contre un entete mal foutu qui ne gere pas les inclusions multiples ?
| > |
| > | Je pense que ce serait plutôt pour les programmeurs qui n'en veulent
| > | pas, pour des applications spécifiques (comme l'implémentation d'une
| > | bibliothèque standard ou des choses de ce niveau).
|
| > Une implémentation d'une bibliothèque standard n'est jamais construite
| > de cette manière là -- autrement, elle est sérieusement bugguée.
|
| OK. Sinon, qu'en est-il des implémentations freestanding?

Elle documente ce qu'elle t'offre. Mais si elle t'offre quelque chose
qui dépend de l'odre de l'inclusion ou avec des macros qui ne marchent
pas bien avec "compiler -DMACRO=VALUE", tu auras un jour ou l'autre de
serieux problemes.

-- Gaby
Avatar
Vincent Lefevre
Dans l'article ,
Gabriel Dos Reis écrit:

Vincent Lefevre <vincent+ writes:

| OK. Sinon, qu'en est-il des implémentations freestanding?

Elle documente ce qu'elle t'offre. Mais si elle t'offre quelque chose
qui dépend de l'odre de l'inclusion ou avec des macros qui ne marchent
pas bien avec "compiler -DMACRO=VALUE", tu auras un jour ou l'autre de
serieux problemes.


L'idée était simple:
_ Si MPFR_NO_STDIO n'est pas définie, alors mpfr.h inclut <stdio.h>
et déclare tout.
_ Si MPFR_NO_STDIO est définie (cas rare), alors mpfr.h n'inclut pas
<stdio.h> et ne déclare pas les prototypes en dépendant (comme si
les fonctions d'entrées/sorties n'existaient pas).

Je ne pense pas que cela pose un quelconque problème.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
espie
Je prefere de tres, tres, tres loin la solution qui consiste a laisser
les entetes a plat.

Il est pour moi infiniment preferable d'expliquer a l'utilisateur de ma
bibliotheque qu'il doit utiliser
#include <stdio.h>
#include <foo.h>
dans le synopsis que de faire les choses a sa place.

D'experience, il y a toujours, toujours des bouts foireux dans un coin
qui vont forcer a reordonner les choses, voire a enlever des entetes ou
a reordonner des trucs sur certains systemes. Dans ce cas-la, c'est
infiniment plus simple de faire les corrections localement, dans le
fichier C qui pose probleme, que de devoir mettre en place des solutions
plus bancales dans un fichier d'entete qui inclut la terre et l'univers.
(et invariablement, sur un gros projet, on va tot ou tard se retrouver
avec des autres d'inclusion foireux, avec un fichier qui veut
#include <a.h>
#include <b.h>
et l'autre
#include <b.h>
#include <a.h>)

Ca permet egalement d'avoir un peu plus de controle sur le temps de
compilation, la protection contre les inclusions multiples prenant
de toutes facons du temps.

Ca rend le code plus comprehensible, ca simplifie largement la tache
de la personne qui va devoir debugguer le portage du code sur un systeme
donne, et ca evite de se donner des casse-tetes pour plus tard.
(style, le genre ou on scinde un bout de bibliotheque en deux, ou on
realise qu'un seul des fichiers d'entete a besoin de stdio.h, et ou on
se retrouve a l'inclure quand meme dans les deux, parce que les
utilisateurs ont pris l'habitude de ne pas inclure stdio.h)

J'ajouterais que, dans la bibliotheque standard C, le statut de stdio.h
est particulier, et excessivement foireux. C'est pratiquement le seul
entete qui soit indispensable rien que pour pouvoir definir d'autres
entetes, et qui ne soit pas uniquement concu dans ce but. Precisement
a cause de FILE *. C'est d'autant plus debile qu'il est evident que FILE
est une struct, et que si on avait defini struct file, voire struct FILE,
dans la norme, on pourrait prototyper des fonctions utilisant des struct
file * sans avoir besoin d'inclure stdio.h.

(les entetes qui servent pour d'autres entetes, par exemple, sont
stdint.h, ou stdarg.h, ou stddef.h)

Evidemment, ce genre de consideration ne commence a s'appliquer
serieusement que pour des projets qui comptent plusieurs centaines de
fichiers source, ou qui doivent etre portables sur quatre ou cinq
architectures fortement distinctes.
Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Vincent Lefevre <vincent+ wrote:

Une implémentation d'une bibliothèque standard n'est jamais construite
de cette manière là -- autrement, elle est sérieusement bugguée.


OK. Sinon, qu'en est-il des implémentations freestanding?


Bah, j'en utilise depuis plus de 10 ans (Intermetrics, Microtek, Texas,
Diab). Jamais eu de problème avec ça. Je ne vois d'ailleurs pas pourquoi il y
aurait plus de problèmes qu'avec du hosted...

--
-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
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:

| _ Si MPFR_NO_STDIO est définie (cas rare), alors mpfr.h n'inclut pas
| <stdio.h> et ne déclare pas les prototypes en dépendant (comme si
| les fonctions d'entrées/sorties n'existaient pas).

As-tu un cas concret -- pas une hypothèse ?

-- Gaby
Avatar
Gabriel Dos Reis
(Marc Espie) writes:

| est particulier, et excessivement foireux. C'est pratiquement le seul
| entete qui soit indispensable rien que pour pouvoir definir d'autres
| entetes, et qui ne soit pas uniquement concu dans ce but. Precisement
| a cause de FILE *. C'est d'autant plus debile qu'il est evident que FILE
| est une struct,

C'est loin d'être évident.

-- Gaby
1 2 3 4 5