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

Due domande:
1) quale dei due procedimenti è quello corretto?
A. Il preprocessore inserisce il codice presente nelle librerie incluse nel
sorgente; poi interviene il compilatore che trasforma il codice così
modificato in linguaggio macchia (binari). Infine, il linker unisce
eventuali vari moduli binari in un file eseguibile
B. Il preprocessore inserisce il codice presente nelle librerie incluse nel
sorgente; poi interviene il compilatore che trasforma il codice così
modificato in linguaggio macchia (binari). Infine, il linker unisce in un
file eseguibile il file oggetto ottenuto dalla compilazione ed i files di
libreria.
Mi sembra di capire che sia vera la B. Ma allora: a che serve l'inclusione
operata dal preprocessore se poi è il linker che realmente inserisce le
funzioni chiamate dal programmatore?
2) Lo stesso codice sorgente, dà origine sempre al medesimo binario
qualunque sia il compilatore usato?
Grazie

 qualunque sia il compilatore usato?
Decisamente no. Anche lo stesso compilatore ha opzioni per dare 
risultati diversi.

 librerie.
Perche le librerie, da quel che ho capito, sono già binarie, giusto? Però,
mi domando, il codice binario inlcuso (quello delle librerie) corrisponde o
no al codice sorgente incluso (quello dei file .h)? Te lo chiedo perchè ho
letto che perchè il linker possa unire il file compilato ed i "pezzi" presi
dalle librerie, è necessario che nel sorgente si specifichi con #include a
quale libreira riferirsi. Così ho pensato: visto che il riferimento al file
.h include un pezzo di codice nel sorgente .c, e visto che questi header
servono poi in qualche modo al linker per scegliere in quali librerie
cercare e cosa cercare, allora le cose potrebbero stare come segue. Il
precompilatore include i file .h nel sorgente .c; il compilatore trasforma
questo sorgente in un binario non ancora definitivo, ottenuto compilando
tutto fuorchè il codice incluso dai file .h. Infine il linker nisce il
codice oggetto così ottenuto con il codice binario delle librerie. In questo
modo il linker serve per aggiungere il codice binario al prodotto della
compilazione, relativo ai segmeni di sorgente inclusi dai file .h.
Ho capito o no?
Grazie

 Grazie
Ciao
Maticu`

 cercare e cosa cercare, allora le cose potrebbero stare come segue. 
Anche questo è sbagliato.
La direttiva #include NON dice nulla al linker. Quali librerie includere 
va detto direttamente al linker, negli IDE lo si fa nel progetto 
altrimenti si specifica nel Makefile.
Facciamo un esempio: supponiamo che tu utilizzi la funzione pippo() 
dichiarata nel file pippo.h e implementata nella libreria pippo.lib.
Se tu includi il file pippo.h, il compilatore è contento e genera il 
file binario: ma se *non* aggiungi pippo.lib al progetto/Makefile, 
quando vai a generare l'eseguibile (solo e soltanto allora) il linker ti 
darà l'errore "Unresolved external: _pippo".
Nell'esempio che ho fatto prima della printf, il fatto che non includi 
stdio.h non fa si che il linker escluda la libreria standard dove è 
definita la printf, la quale è implicitamente inclusa per default.

 dichiarata nel file pippo.h e implementata nella libreria pippo.lib.
Questo è il punto cruciale: io pensavo che la funzione nel file .h fosse
_definita_ e non solo _dichirata/prototipata_
Da qui i miei dubbi....
Grazie al tuo mes ho capito che non è così: ho aperto il file stdio.h ed ho
trovato, rispetto a printf neppure una riga, una dichiarazione penso.
Insomma, io credevo che negli .h le funzioni fossero definite e non solo
dichiarate.
Ora mi è tutto chiaro, compreso il fatto che quindi la printf non è così
definita da nessuna parte, ma è in un certo senso "esterna" al C e viene
importata (in forma già binaria) dal linker.
Un'ultima cosa: ma negli .h ci posso mettere solo dichiarazioni? Se cioè
creo un file lo.h, che contiene una definizione di funzione e poi lo
includo, cosa accade?
Es. di lo.h
int pippo(void)
{
    int gre;
    scanf("%d",&gre);
    return 0;
}
In altre parole: posso usare una direttiva #include per appiccicare un pezzo
di codice scritto altrove al sorgente che la contiene (la direttiva,
intendo)?
Grazie

 cui verrebbe richiamata non saprebbe dove andarla a ricercare.
Quindi il linker scorre il codice oggetto e vede che alcune funzioni
mancano, e le cerca nelle librerie! Ma come fa a sapere in quale libreria
cercare? Da quello che ho capito non è certo l'include ad indicarla. L'
include indica dove si trova il prototipo della funzione.
Mi sorge un pesnierino. Forse sto dicendo un'assurdità, ma a questo punto il
codice presente nella libreria potrebbe essere stato scritto anche in un
altro linguaggio?
Grazie

 cui verrebbe richiamata non saprebbe dove andarla a ricercare.


 altro linguaggio?
Ovviamente sì, ad esempio il codice della libreria del Turbo C era
scritto, per la maggior parte, in assembly.  Altro esempio: quando si
sviluppava in Clipper, si coprivano certe mancanze del linguaggio
scrivendo opportune routine in C.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 intendo)?
Concettualmente: č sbagliato.
Praticamente: provaci e vedi se č possibile no ?

 Praticamente: provaci e vedi se è possibile no ?
Perfetto!
 Grazie mille

 scrivendo opportune routine in C.
Perfetto!
Grazie!

 libreria cercare?
Il linker sa qual è il percorso in cui sono presenti le librerie (glielo
dici tu o l'ambiente di sviluppo) e si sfoglia tutti i file di libreria
che trova.
Un caso a parte è il caricamento di librerie a run-time (come avviene
sotto Windows con le DLL) per il quale la procedura è tutta diversa.


 sotto Windows con le DLL) per il quale la procedura è tutta diversa.
Grazie mille a tutti!
I miei complimenti per la competenza e la chiarezza espositiva!