Newsgroup: it.comp.lang.c
Titolo: include

prechè i programmi C funzionano anche senza include?


«Se dio esiste, spero che abbia una scusa valida.»
(D. Pennac)

 prechč i programmi C funzionano anche senza include?
Perche'  alcuni compilatori/IDE  sono  ``intelligenti''  e li  includono
*quando* te ne dimentichi. Il che  non significa che tu debba ometterli,
lasciando fare al compilatore.
-- 
Emmanuele Bassi         |     [ 
http://digilander.iol.it/ebassi/linux/
 ]
   (Zefram)             |                     [ 
emmanue...@iol.it
 ]
                        |                 WARNING: Email Address is FAKE
GnuPG Key Fingerprint: 9747 635E B95A B0B3 4370 1CAA CAF7 512B 945C A44C

prechč i programmi C funzionano anche senza include?
I motivi possono essere due; il tuo programma C non usa
nessuna funzione di libreria oppure sei fortunato.
Mi spiego: un programma C fatto in questo modo...
    int main()
    {
      return 0;
    }
Non ha chiamato nessuna funzione di libreria e quindi
non e' necessario che contenga alcun header.
Una seconda possibilita' e' che la deduzione del tipo
di argomenti e della convenzione di chiamata fatta dal
compilatore C sia quella giusta per le funzioni di
libreria che chiami. Se scrivi ad esempio
      int x=atoi("6502");
senza includere <stdlib.h> il compilatore dedurra' che
atoi sia una funzione che restituisce un intero (giusto)
e che accetta un puntatore a carattere (non giustissimo
ma accettabile). In questo caso c'e' una buona
probabilita' che la cosa "funzioni lo stesso".
Se pero' scrivi qualcosa come:
      double x=cos(1);
e non hai incluso <math.h> (che dichiara la funzione cos)
allora il compilatore si buttera' ad indovinare e
immaginera' che la funzione "cos" che non hai dichiarato
accetti un parametro intero (cosa errata) e che
restituisca un intero (altra cosa falsa). In questo caso
le probabilita' che la cosa "funzioni" sono bassissime.
La deduzione automatica del tipo e dei parametri di
una funzione e' una cosa vecchia che e' rimasta per
compatibilita' con il passato. Nei programmi e' sempre
di gran lunga preferibile dichiarare tutte le funzioni
prima di usarle per evitare errori subdoli di questo tipo.
Un compilatore moderno dovrebbe generare dei warning
quando usi funzioni non dichiarate.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 le probabilita' che la cosa "funzioni" sono bassissime.
Qui probabilmente la compilazione non andrebbe neppure a buon fine, perche'
si deve in linkare la libreria con le funzioni matematiche (con -lm o una
cosa del genere...), o sbaglio?
-- 
 Ciao, Bianco.
 Reply to luca.bianco (at) 
tiscalinet.it

  Ciao, Bianco.
Se ne dovrebbe occupare il linker, non il compilatore...

 Se ne dovrebbe occupare il linker, non il compilatore...
Usando il gcc in console fai tutto in un comando, tipo:
gcc programma.c -o programma -lm


gcc programma.c -o programma -lm
In questo caso il compilatore gcc (come fanno altri) chiama
da solo anche il linker; ma -lm e' un problema del linker,
non del compilatore.
In ogni caso la questione originale era un'altra. Se in un
modulo di un programma C tu scrivi
     x=cos(1);
senza aver incluso <math.h> allora la compilazione di quel
modulo comunque procede (anche se un compilatore serio ti
dovrebbe avvisare che ha incontrato una funzione senza
prototype e che quindi e' stata fatta la deduzione automatica
dei parametri e del valore di ritorno).
Se poi fai il link dei vari moduli usando -lm (che magari ti
sei ricordato di mettere perche' in qualche *ALTRO* modulo hai
usato #include <math.h>) allora anche il link riuscira' a
completare la sua fase e tu ti troverai con un eseguibile.
Che pero' non fara' cose sensate nel momento che incontra
la chiamata a cos compilata senza una corretta dichiarazione.
La deduzione automatica del prototype del "C" e' veramente
solo un retaggio dei tempi antichi e l'unico vantaggio che
ha e' quello di rendere piu' complicata la fase di ricerca
dei problemi (se qualcuno considera questo un vantaggio).
In C++ (per fortuna) e' stato deciso che questa "feature"
del C non interessava, anzi disturbava parecchio; anche al
prezzo di perdere su questo la compatibilita' con il C, in
C++ il chiamare una funzione che non sia stata dichiarata
e' un errore (e questo e' bene :) ).


 dei parametri e del valore di ritorno).
Basta abituarsi a compilare sempre con -Wall, in modo che non sfugga nulla,
o quasi.
