Newsgroup: it.comp.lang.c
Titolo: Creazione di librerie.

Ciao a tutti.
In una libreria chiamata g_lib.a, ho aggiunto tre file, chiamati 
gfopen.o, gcalloc.o e gmalloc.o. 
A titolo di esempio, vi posto il codice (niente di speciale) del file 
sorgente gfopen.c. 
***
//Versione personalizzata di fopen(). 
//Chiama fopen() e, qualora questa fallisca, stampa un messaggio di 
errore ed esce dal programma principale.
FILE *gfopen(const char *path, const char *mode) {
 FILE *fp;
 
 if ((fp = fopen(path, mode)) == NULL) {
  fprintf(stderr, "Non posso aprire il file %s. Programma terminato.\n", 
path);
  exit(1);
 }
 return fp;
} 
 
Come vedete, in questa versione, compilata da riga di comando con bcc32 
di Borland sotto Windows, non ho avuto bisogno di includere gli header 
files stdio.h e stdlib.h. 
Lo stesso testo, compilato sotto linux con gcc,  (gcc -c gfopen.c), 
genera un errore che non porta a termine la compilazione. L'unico modo 
che ho per compilarlo correttamente è includere i due header files di 
cui sopra. 
Qualcuno sa spiegarmi il perché di questa differenza di comportamento 
tra i due sistemi operativi?
In generale, è o non è buona prassi includere i sopra citati file nei 
file sorgente delle funzioni di libreria? Più in generale, se una 
funzione destinata a far parte di una libreria chiama un'altra funzione 
appartenente alla libreria standard, è necessario includere in essa lo 
header corrispondente?
Sperando di essermi spiegato, vi ringrazio e vi saluto con cordialità.
Bizio.

 header corrispondente?
In questo caso non mettere i .h e' proprio un errore, ma in generale
e' sbagliato non includerli perche' il c di default quando incontra
delle funzioni di cui non ha la dichiarazione assume che ritornino
sempre int, e questo a volte puo' creare problemi. Meglio sempre 
includere tutti i .h che servono.
ciao
Giacomo

In C, preferisco non includere header in altri header.
Se un header dipende da un altro, lo metto nella documentazione.
Questa e' la prassi usata dagli header standard: nessun header
standard  include altri header standard.
Se un header standard ha bisogno di un altro header standard, e'
scritto nella documentazione (man pages) e devi includerli entrambi,
nell'ordine corretto, nel modulo che li usa.
E' una vecchia raccomandazione di Rob Pike, ed e' quella usata dal
sistema operativo Plan9, il successore spirituale (perche' creadto
dagli stessi autori) di Unix.
La cosa puo' sembrare strana, ma riduce il numero di header file che
vengono generati da una libreria ed infatti, in plan9, la regola e'
che dovresti usare un solo header (API pubblica) per libreria.
Su Plan9, invece dei vari header standard, hanno solo l'header libc.h
Per referenza, ecco l'HOWTO del compilatore di Plan9:
http://www.lysator.liu.se/c/plan9c.html

 Se un header dipende da un altro, lo metto nella documentazione.
Si si questa e' una delle due "fazioni" della "guerra di religione sugli
header file" quindi non voglio sbilanciarmi in commenti! :)
Spero comunque che tu sia d'accordo con me che se usi
printf nella tua libreria da qualche parte (nel tuo .h o
nel codice del cliente) sia bene includere stdio.h
ciao
Giacomo

On 27 Nov, 19:10, Giacomo Degli Esposti

Se uso printf nel .c, usero' quasi sicuramente stdio.h (a meno che sia
su una piattaforma non conformante)
Ma se il mio header dipende da stdio.h (per esempio per il tipo FILE),
lo metto nella documentazione.
Anche perche' il mio header non dipende da stdio.h, ma dalle
dichiarazioni in stdio.h
Se il cliente vuole mettere le proprie dichiarazioni da una libreria
non standard ma compatibile (questo e' importante) con stdio, puo'
farlo.
Attualmente lavoro per una compagnia in cui cio' non e' possibile su
larga scala, ovvero usiamo C++.
Ma siccome i file .h includono altri .h, se ci sono due file .h con lo
stesso nome ma in directory diverse, i problemi legati a quale dei .h
viene incluso diventa veramente un problema.
Sto parlando di un progetto con oltre 20.000 file (in totale, tra c,
h, cpp, py)
All'orche allennesima volta che il file sbagliato veniva incluso, ho
suggerito la tecnica di cui sopra, limitatamente a quel sotto progetto
(C++), e il problema e' scomparso.
E' una cosa di cui ormai sono convinto: se devi documentare qualcosa,
nel farlo riduci i problemi, e semplifichi. Invece di decine di .h che
si includono a vicenda, e a volte si contraddicono, si riduce il
numero ad un sopra insieme piu' piccolo, ben definito, e si vive
meglio.
Questa e' la mia esperienza.

 
http://www.lysator.liu.se/c/plan9c.html
Per curiosità, qual è lo stato di Plan9? E' un OS utilizzabile su un 
home computer?
E.


L'ho installato su vmware e funziona discretamente bene. E' un sistema
operativo giocattolo, ma le idee base sono molto buone.
Adesso il cuore di Plan9 viene utilizzato su Inferno. Ma non sono
aggiornato sullo stato commerciale di Inferno.