Il compilatore C allegherà l'intero codice oggetto del file di intestazione?

2

Quando compili un codice sorgente C il compilatore converte l'intero file di intestazione in codice oggetto o solo le funzioni del file di intestazione che usi?

Come per esempio, nel file di intestazione #include stdio.h, ci sono printf (); e scanf (); ma anche per usare uno di questi, devi includere il file di intestazione "stdio.h", quindi quando compili un codice sorgente C che usa solo printf (); ma non usa scanf () ;, il compilatore includerà anche il codice oggetto di scanf (); e altre funzioni di "stdio.h" nel file?

    
posta want2code 05.03.2015 - 06:00
fonte

3 risposte

6

Il compilatore genererà il codice per tutto.

Il linker può (e di solito non include) il codice di funzioni inutilizzate nell'esecuzione finale.

L'implementazione, ovviamente, varia da linker a linker.

    
risposta data 05.03.2015 - 08:47
fonte
5

Indirettamente, sì.

Per sapere cosa succede al codice nel file di intestazione, è necessario capire come il compilatore li gestisce.

La direttiva #include

La direttiva #include è una direttiva preprocessore. Anche prima che il compilatore inizi ad analizzare e tradurre il codice, elaborerà tutto #include s inserendo l'intero codice nel file di intestazione specificato nella posizione dell'istruzione #include . (Puoi vedere cosa sputa il preprocessore quando usi, per esempio, gcc -E ... sui tuoi file sorgente.)

Ecco perché include le guardie sono importanti.

Quindi la risposta alla tua domanda è: Sì, il codice nei file di intestazione è tradotto in un file oggetto - per essere precisi nel file oggetto del primo file sorgente tradotto che lo include in un'unità di traduzione.

Le definizioni nei file di intestazione devono essere note in ogni unità di traduzione che utilizza le definizioni. Se traduci il tuo file di programma per file e lo colleghi in seguito, avrai il codice nel file di intestazione compilato più volte. Questo è il motivo per cui dovresti mettere l'implementazione in un file sorgente separato. Se lo fai, dichiarerai ogni funzione solo in ogni unità di traduzione, ma non tradurrai l'implementazione. Tutti i file saranno quindi collegati al file di un oggetto con l'implementazione.

    
risposta data 05.03.2015 - 08:41
fonte
2

Il compilatore non fa nulla con altri file oggetto. Si limita a compilare il codice per i file oggetto un'unità di traduzione alla volta. È il linker che prende il nuovo file oggetto, cerca simboli come "printf" e quindi "attacca" l'implementazione di printf dal file oggetto di stdio.h. In teoria il linker potrebbe lanciare l'intero file oggetto stdio.h, ma in pratica dovrebbe lasciare fuori tutto il codice scanf nell'eseguibile finale poiché non ne hai bisogno.

Quindi la risposta letterale alla tua domanda è: No, il compilatore non fa nulla del genere. Se si utilizza "compiler" per indicare in modo informale l'intera toolchain, la risposta è: Sì all'inizio, ma solo fino a quando non viene terminata la verifica di quali parti del file oggetto si eseguono e non sono necessarie.

Si noti che questo descrive solo il collegamento statico, in cui si combinano tutti i file oggetto in un singolo eseguibile prima di eseguire qualsiasi cosa. Il collegamento dinamico è una storia molto diversa.

    
risposta data 05.03.2015 - 09:08
fonte

Leggi altre domande sui tag