Come ragiona il compilatore?

Alcuni test sul blink: La compilazione occupa 1018byte Ho aggiunto una void() senza richiamarla da nessuna parte, la compilazione l'ha ignorata Poi l'ho richiamata dal loop, la compilazione ha dato un valore di memoria più elevato. Poi ho richiamato il blink originale e questa volta ho incluso la lib del "servo" (una a caso) senza usare nello sketch alcun richiamo ad essa. La compilazione ha dato un valore di memoria più elevato. Domanda: Perché le righe di istruzione inutilizzate vengono ignorate e le lib invece occupano comunque della memoria, pur non essendo utilizzate nello sketch?

Le istruzioni inutilizzate vengono ignorate dal compilatore, mentre le librerie non sono pane del compilatore , ma del loader (ld) che le carica comunque.

BrainBooster: Le istruzioni inutilizzate vengono ignorate dal compilatore, mentre le librerie non sono pane del compilatore , ma del loader (ld) che le carica comunque.

ld.exe è il linker, il loader è un'altra cosa, e non ha nulla a che vedere con l'inclusione di codice nel sorgente come nel caso delle librerie di arduino dove hai almeno un file .h di include e un .cpp di codice vero e proprio più altri eventuali file accessori, il linker tratta solo i file oggetto, cioè compilati senza aver risolto gli indirizzi, e l'eventuale inclusione di codice da librerie precompilate a patto che venga realmente richiamato dal sorgente. Il motivo per cui aggiungendo una libreria sotto forma di "#include qualcosa" le dimensioni del codice possono aumentare anche non utilizzando funzioni della libreria è perché vengono comunque definite variabili di ambiente, spesso di tipo statico, inizializzate delle periferiche etc, tutte cose richiedono righe di codice che vengono eseguite sempre e comunque.

astrobeed: Il motivo per cui aggiungendo una libreria sotto forma di "#include qualcosa" le dimensioni del codice possono aumentare anche non utilizzando funzioni della libreria è perché vengono comunque definite variabili di ambiente, spesso di tipo statico, inizializzate delle periferiche etc, tutte cose richiedono righe di codice che vengono eseguite sempre e comunque.

Quindi lo spazio occupato è solo quello di queste variabili?

Cioè, se invece io inserissi dei comandi inerenti la libreria, a parte le righe aggiunte, verrebbero "caricate" anche altre parti della libreria in memoria?

menniti: verrebbero "caricate" anche altre parti della libreria in memoria?

Io so che quando includi una libreria statica essa viene compilata per intero e immersa nel codice finale... tutta. Anche se non utilizzi nessuna chiamata o cose del genere...

...ecco perchè nacquero le dll

è vero , mi sono confuso, ld non centra nulla :P

Trisonic:

menniti: verrebbero "caricate" anche altre parti della libreria in memoria?

Io so che quando includi una libreria statica essa viene compilata per intero e immersa nel codice finale... tutta. Anche se non utilizzi nessuna chiamata o cose del genere...

...ecco perchè nacquero le dll

Ma Astro dice

....e l'eventuale inclusione di codice da librerie precompilate a patto che venga realmente richiamato dal sorgente.

@ BB: se ho ben capito LD c'entra, solo che è il linker e non il loader...

menniti:

Trisonic:

menniti: verrebbero "caricate" anche altre parti della libreria in memoria?

Io so che quando includi una libreria statica essa viene compilata per intero e immersa nel codice finale... tutta. Anche se non utilizzi nessuna chiamata o cose del genere...

...ecco perchè nacquero le dll

Ma Astro dice

....e l'eventuale inclusione di codice da librerie precompilate a patto che venga realmente richiamato dal sorgente.

effettivamente si, è un ottimizzazione

... e 2 @menniti hai ragione anche tù ho fatto un doppio casino. in verità volevo solo dire che se ne occupa il linker.

Trisonic: Io so che quando includi una libreria statica essa viene compilata per intero e immersa nel codice finale... tutta. Anche se non utilizzi nessuna chiamata o cose del genere...

No, se hai una ipotetica libreria con dentro 100 funzioni e nel tuo codice ne usi effettivamente solo 10 verrà aggiunto, e compilato, solo il codice strettamente necessario e le eventuali dipendenze. Le dll sono una cosa diversa, permettono di avere una sola libreria precompilata comune a più programmi ed esterna a questi, in questo modo ottieni eseguibili molto piccoli che attingono dalle varie dll il codice necessario al loro funzionamento invece di avere tanti eseguibili molto grossi con molto codice ridondante.

Trisonic: Io so che quando includi una libreria statica essa viene compilata per intero e immersa nel codice finale... tutta. Anche se non utilizzi nessuna chiamata o cose del genere...

...ecco perchè nacquero le dll

ciao

la cosa è un po' diversa... le DLL ti danno alcuni vantaggi:

  • possono essere "riutilizzate" da più programmi
  • sono caricate "a runtime", quindi puoi aggiornarle senza dover ricompilare anche il programma che ne fa uso
  • possono essere "condivise": eventuali metodi statici ad es. vengono caricati solo una volta in memoria e possono essere chiamati da più programmi senza essere duplicati

bye

avresti un motivo per volerlo? 8)

Basta disabilitare le ottimizzazioni del compilatore, ad esempio compilando in modalità "debug" ti trovi tutto e di più, è utile in genere quando si esegue passo passo il codice

Non parlavo dei simboli di debug ma della "modalità debug" che è presente spero in AvrStudio (io la uso in compilatori come Visual C++ e in pratica va a mettere/togliere in automatico diversi flag sul compilatore). Su gcc non ti so aiutare su quali flag mettere o togliere

ciao

se dovessi cercare, non cercherei nelle opzioni di compilazione ma in quelle del linker, è infatti questo step che va a unire le porzioni di codice delle librerie (spesso pre-compilate in .a) nell'eseguibile ed è quindi il linker che ottimizza le "inclusioni" di codice selezionando solo quello effettivamente necessario.

Guardando qui: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

non trovo però nulla che dica di includere in toto le varie librerie...

Scusate, ma la compilazione statica compila tutta la libreria, con tutte le eventuali dipendenze, infatti spesso in Linux si usano queste per garantire il minor numero di dipendenze possibili, ma aumentano in modo considerevole le dimensioni, quello che diceva astro se nn sbaglio riguarda la compilazione dinamica, almeno cosi ricordo su gcc

Asp e ho detto na cassata, [ il linker estrae dalla libreria statica solo i moduli strettamente necessari alla compilazione del programma. Questo dimostra una certa capacità di economizzare le risorse delle librerie. Pensiamo però a più programmi che utilizzano, magari per altri scopi, la stessa libreria statica. I programmi utilizzano la libreria statica distintamente, cioè ognuno ne possiede una copia. Se questi devono essere eseguiti contemporaneamente nello stesso sistema, i requisiti di memoria si moltiplicano di conseguenza solo per ospitare funzioni assolutamente identiche.]

Per riassumere:

Librerie statiche:

Ogni processo ha la sua copia della libreria statica che sta usando, caricata in memoria.

Gli eseguibili collegati con librerie statiche sono più grandi.

Librerie condivise:

Solo una copia della libreria viene conservata in memoria ad un dato istante (sfruttiamo meno memoria per far girare i nostri programmi e gli eseguibili sono più snelli).

I programmi partono più lentamente.

P.s quanto ? bello google:)

direi che hai capito ;)

astrobeed: No, se hai una ipotetica libreria con dentro 100 funzioni e nel tuo codice ne usi effettivamente solo 10 verrà aggiunto, e compilato, solo il codice strettamente necessario e le eventuali dipendenze.

grazie per la dritta astro! vuol dire che all'uni avrò capito male!