<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//IT">
<HTML>
<HEAD>
 <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <META NAME="GENERATOR" CONTENT="lfparser_2.25">
 <META NAME="LFCATEGORY" CONTENT="SoftwareDevelopment">
<!-- this is used by a number of tools:
 =LF=AUTHOR: Lorne Bailey
 =LF=CAT___: SoftwareDevelopment
 =LF=TITLE_: GCC - la radice di tutto
 =LF=NUMBER: 229
 =LF=ANAME_: article229.shtml
 -->
 <TITLE>lf229, SoftwareDevelopment: GCC - la radice di tutto</TITLE>
<!-- stylesheet added by lfparser: --> 
<style type="text/css">
<!--
 td.top {font-family: Arial,Geneva,Verdana,Helvetica,sans-serif; font-size:12 }
 pre { font-familiy:monospace,Courier }
 p.cl { color:#EE9500 }
 a.nodec { text-decoration:none }
 p.trans { font-size:8pt; text-align:right }
 p.clbox { width:50%; alignment:center; background-color:#FFD700; border-style:none; border-width:medium; border-color:#FFD700; padding:0.5cm ;  text-align:center }
 p.code { width:80%; alignment:center; background-color:#aedbe8; border-style:none; border-width:medium; border-color:#aedbe8; padding:0.1cm ;  text-align:left }
 p.foot { background-color:#AAAAAA; color:#FFFFFF; border-style:none; border-width:medium; border-color:#AAAAAA; padding:0.5cm ; margin-top:0.1cm; margin-right:1cm; margin-left:1cm; text-align:center }
-->
</style>
 
</HEAD>
<BODY bgcolor="#ffffff" text="#000000">
 <!-- this is generated html code. NEVER use this file for your
 translation work. Instead get the file with the same article number
 and .meta.shtml in its name. Translate this meta file and then
 use lfparser program to generate the final article -->
 <!-- lfparser can be obtained from http://www.linuxfocus.org/~guido/dev/lfparser.html -->

<!-- 2pdaIgnoreStart -->

<!-- start navegation bar -->
 <!-- top navegation bar -->
 <TABLE summary="topbar_1" cellspacing="0" cellpadding="0" border="0" align="center" width="90%">
   <TR bgcolor="#2e2292">
     <TD class="top"><TABLE summary="topbar_1_logo" cellspacing="0" cellpadding="0" border="0" width=
       "100%">
         <TR><TD width="319"><IMG src="../../common/images/logolftop_319x45.gif"
           alt="[LinuxFocus-icon]" width="319" height="45" align="left" 
           border="0"></TD>

           <TD class="top">
             <TABLE summary="topbar_1_links" width="100%">
               <TR align="right">
                 <TD class="top"><A class="nodec" href="../index.shtml"><FONT color=
                 "#DDDDDD" size="2">Home</FONT></A> &nbsp;|&nbsp; <A class=
                 "nodec" href="../map.html"><FONT color=
                 "#DDDDDD" size="2">Mappa</FONT></A> &nbsp;|&nbsp; <A class=
                 "nodec" href="../indice.html"><FONT color=
                 "#DDDDDD" size="2">Indice</FONT></A> &nbsp;|&nbsp; <A class="nodec" href="../Search/index.shtml"><FONT color=
                 "#DDDDDD" size="2">Cerca</FONT></A> </TD>
               </TR>

               <TR align="right">
                 <TD class="top">
                   <HR width="100%" noshade size="1">
                 </TD>
               </TR>
             </TABLE>
           </TD>
         </TR>
       </TABLE>
     </TD>
   </TR>
 </TABLE>
 <!-- end top navegation bar -->
 <!-- blue bar -->
 <TABLE summary="topbar_2" cellspacing="0" cellpadding="0" border="0" align="center"
 width="90%">
   <TR bgcolor="#00ffff">
     <TD><IMG src="../../common/images/transpix.gif" width="1" height=
     "2" alt=""></TD>
   </TR>
 </TABLE>
 <!-- end blue bar -->
 <!-- bottom navegation bar -->
 <TABLE summary="topbar_3" cellspacing="0" cellpadding="0" border="0" align="center"
 width="94%">
   <TR bgcolor="#000000">
     <TD>
       <TABLE summary="topbar_3_links" cellspacing="0" cellpadding="1" border="0" width=
       "100%">
         <TR align="center">
           <TD WIDTH="20%"><A class="nodec" href="../News/index.shtml"><FONT color=
           "#FFFFFF">News</FONT></A> </TD>
           <TD WIDTH="5%"><FONT color="#FFFFFF">|</FONT> </TD>
           <TD WIDTH="20%"><A class="nodec" href="../Archives/index.html"><FONT color=
           "#FFFFFF">Archivo</FONT></A> </TD>
           <TD WIDTH="5%"><FONT color="#FFFFFF">|</FONT> </TD>
           <TD WIDTH="20%"><A class="nodec" href="../Links/index.html"><FONT color=
           "#FFFFFF">Link</FONT></A> </TD>
           <TD WIDTH="5%"><FONT color="#FFFFFF">|</FONT> </TD>
           <TD WIDTH="20%"><A class="nodec" href="../aboutus.html"><FONT color=
           "#FFFFFF">Cose LF</FONT></A> </TD>
         </TR>
       </TABLE>
     </TD>
   </TR>
 </TABLE>
 <!-- end bottom navegation bar -->
<!-- stop navegation bar -->

<!-- SSI_INFO -->

<!-- tr_staticssi include virtual -->
<!-- tr_staticssi exec cmd -->
<!-- addedByLfdynahead ver 1.1 --><TABLE ALIGN="right" border=0><TR><TD ALIGN="right"><FONT SIZE="-1" FACE="Arial,Helvetica">Questo articolo &egrave; disponibile in: <A href="../../English/March2002/article229.shtml">English</a> &nbsp;<A href="../../Castellano/March2002/article229.shtml">Castellano</a> &nbsp;<A href="../../ChineseGB/March2002/article229.shtml">ChineseGB</a> &nbsp;<A href="../../Deutsch/March2002/article229.shtml">Deutsch</a> &nbsp;<A href="../../Francais/March2002/article229.shtml">Francais</a> &nbsp;<A href="../../Italiano/March2002/article229.shtml">Italiano</a> &nbsp;<A href="../../Portugues/March2002/article229.shtml">Portugues</a> &nbsp;<A href="../../Russian/March2002/article229.shtml">Russian</a> &nbsp;<A href="../../Turkce/March2002/article229.shtml">Turkce</a> &nbsp;<A href="../../Arabic/March2002/article229.shtml">Arabic</a> &nbsp;</FONT></TD></TR></TABLE><br>
 


<!-- SSI_INFO STOP -->
<!-- 2pdaIgnoreStop -->

<!-- SHORT BIO ABOUT THE AUTHOR -->
<TABLE ALIGN=LEFT BORDER=0  WIDTH="190" >
<TR>
<TD>

<!-- 2pdaIgnoreStart -->
<!-- PALM DOC -->
<TABLE BORDER=0 hspace=4 vspace=4> <TR> <TD>
<font size=1> <img src="../../common/images/2doc.gif" width=34 align=left border=0 height=22 alt="convert to palm"><a href="http://cgi.linuxfocus.org/cgi-bin/2ztxt">Convert to GutenPalm</a><br>or <a href="http://cgi.linuxfocus.org/cgi-bin/2pda">to PalmDoc</a></font>
</TD> </TR> </TABLE>
<!-- END PALM DOC -->
<!-- 2pdaIgnoreStop -->
<br>
<img src="../../common/images/LorneBailey.gif"  width="178" height="200"
alt="[Lorne Bailey]">
<BR>   Lorne Bailey <br> <small>&lt;sherm_pbody(at)yahoo.com&gt;</small>
<BR><BR>
<I>L'autore:</I><BR>
<P>
Lorne vive a Chicago a lavora come consulente informatico specializzato
nel mettere e togliere dati in un database Oracle.
Fin da quando &egrave; passato a programmare esclusivamente in ambiente
*nix, Lorne ha completamente evitato l'"inferno DLL".
Attualmente sta lavorando alla sua tesi in Scienze Informatiche.
</P>
<!-- TRANSLATED TO it -->
<BR><BR><I>Tradotto in Italiano da:</I><BR>
Alessandro Pellizzari <small>&lt;alex(at)neko.it&gt;</small>
<br>
<!-- TRANSLATED TO STOP -->
<BR><i>Contenuto</i>:
<UL>
  <LI><A HREF="#229lfindex0"> Le regole di GCC </A></LI>
  <LI><A HREF="#229lfindex1"> All'inizio... </A></LI>
  <LI><A HREF="#229lfindex2">
 Pre-compilazione
</A></LI>
  <LI><A HREF="#229lfindex3">
Compilazione
</A></LI>
  <LI><A HREF="#229lfindex4">
Assembly
</A></LI>
  <LI><A HREF="#229lfindex5">
Link
</A></LI>
  <LI><A HREF="#229lfindex6">
Altre Due Opzioni Importanti
</A></LI>
  <LI><A HREF="#229lfindex7">
Debugging
</A></LI>
  <LI><A HREF="#229lfindex8">
Conclusioni
</A></LI>
  <LI><A HREF="#229lfindex9">
Links
</A></LI>
  <LI><A HREF="http://cgi.linuxfocus.org/cgi-bin/lftalkback?anum=229&amp;lang=it">Discussioni su quest'articolo</A></LI>
</UL>

</TD></TR></TABLE>
<!-- HEAD OF THE ARTICLE -->
<br>&nbsp;
<H2>GCC - la radice di tutto</H2>
 <IMG SRC="../../common/images/illustration229.gif" ALT="[Illustration]"
HSPACE=10 width="200" height="60">
<!-- ABSTRACT OF THE ARTICLE -->
<P><i>Premessa</i>:
<P>

Questo articolo presuppone che conosciate le basi del linguaggio C,
e vi introdurr&agrave; all'uso di gcc come compilatore. Controlleremo che
possiate richiamare il compilatore dalla linea di comando con un
semplice sorgente in C.
Quindi daremo una rapida occhiata a quello che succede e a come potete
controllare la compilazione dei vostri programmi.
Daremo anche un veloce sguardo all'uso di un debugger.

</P>
<HR size="2" noshade align="right"><BR>
<!-- BODY OF THE ARTICLE -->


<A NAME="229lfindex0">&nbsp;</A>
<H2> Le regole di GCC </H2>

<p>
Riuscite a immaginare di compilare software free con un compilatore proprietario
e closed-source? Come sapreste cosa sta succedendo nel vostro eseguibile?
Ci potrebbero essere tutti i tipi di backdoor o di trojan.
Ken Thompson, in uno dei migliori hack di tutti i tempi, scrisse un
compilatore che lasciava una backdoor nel programma 'login' e che replicava il
trojan quando il compilatore si accorgeva di ricompilare se stesso. Leggete
la descrizione di questo grande classico
 <a href="http://www.acm.org/classics/sep95">qui</a>.
Fortunatamente abbiamo gcc.
Ogni volta che fate <code> configure; make; make install </code>
gcc fa un bel po' di sollevamento pesi dietro le quinte.
Come possiamo fare in modo che gcc lavori per noi?
Inizieremo scrivendo un gioco di carte, ma scriveremo solo
quello che basta per dimostrare le possibilit&agrave; del compilatore.
Visto che stiamo iniziando da zero, c'&egrave; bisogno di capire il processo
di compilazione per capire cosa deve essere fatto per creare un eseguibile
e in che ordine.
Daremo un'occhiata generale a come un programma in C viene compilato e
alle opzioni che fanno fare al gcc quello che vogliamo che faccia.
I passi (e i tool che li fanno) sono <a
href="#precomp">Pre-compilazione</a> (gcc -E), <a href="#comp">Compilazione</a> (gcc), <a
href="#assem">Assembly</a> (as), and <a href="#link">Link</a> (ld).
</p>

<A NAME="229lfindex1">&nbsp;</A>
<H2> All'inizio... </H2>

<p>
Prima di tutto dovremo sapere come richiamare il compilatore. In verit&agrave;
&egrave; semplice. Inizieremo col classico primo programma in C. (I veterani
dovranno perdonarmi).
</p>
<p>
<pre>
#include &lt;stdio.h&gt;

int main()<br/>
{
  printf("Hello World!\n");
}
</pre>
</p>

<p>
salvate questo file come <code>game.c</code>.
Potete compilarlo dalla linea di comando lanciando:
<pre>
gcc game.c
</pre>
Di default il compilatore C crea un eseguibile chiamato <code>a.out</code>.
Potete lanciarlo scrivendo:
<pre>
a.out
<b>Hello World</b>

</pre>
Ogni volta che compilate un programma, il nuovo
<code>a.out</code> sovrascrive il precedente programma.
Non sarete in grado di capire quale programma abbia generato
l'attuale <code>a.out</code>.
Possiamo risolvere questo problema dicendo al gcc che nome dare
all'eseguibile con l'opzione <code>-o</code>.
Chiameremo questo programma <code>game</code>,
anche se potremmo nominarlo come vogliamo, visto che il C non ha le
restrizioni di Java sui nomi.
<pre>
gcc -o game game.c
</pre>
<pre>
game
<b>Hello World</b>

</pre>
</p>
<p>
A questo punto siamo abbastanza lontani dall'avere un programma utils.
Se pensate che ci&ograve; sia un male, dovreste considerare il fatto che abbiamo
un programma che si compila e funziona. Man mano che aggiungeremo funzioni
a questo programma vogliamo essere sicuri di mantenerlo funzionante.
Sembra che ogni programmatore che inizia voglia scrivere 1.000 linee
di codice e quindi correggerle tutte in una volta. Nessuno, e intendo nessuno,
pu&ograve; fare una cosa del genere. Fate un programma che funziona, fate dei
cambiamenti, lo fate funzionare ancora. Questo limita gli errori che
dovrete correggere ogni volta. Inoltre saprete esattamente cosa avrete
fatto che non funziona, quindi saprete dove concentrarvi.
Questo vi evita di creare qualcosa che <b>voi</b> pensate deva funzionare,
e magari si compila anche, ma non potr&agrave; mai diventare un eseguibile.
Ricordate che il fatto che si compili non significa che funzioni bene.
</p>
<p>
Il nostro prossimo passo &egrave; di creare un file header per il nostro gioco.
Un file header concentra le dichiarazioni di funzioni e tipi di dati in
un solo posto. Questo garantisce che le strutture dati siano definite
in modo consistente in modo che ogni parte del nostro programma veda
ogni cosa esattamente allo stesso modo.
</p>
<pre>
#ifndef DECK_H
#define DECK_H

#define DECKSIZE 52

typedef struct deck_t
{
  int card[DECKSIZE];
  /* numero di carte usate */
  int dealt;
}deck_t;

#endif /* DECK_H */
</pre>
<p>
Salvate questo file come <code>deck.h</code>. Solo i file con estensione
<code>.c</code> vengono compilati,
quindi dovremo cambiare il nostro game.c
Alla linea 2 di game.c scrivete
<code>#include "deck.h"</code>.
Alla linea 5 scrivete
<code>deck_t deck;</code>
Per avere la certezza di non aver introdotto errori, compilatelo di nuovo.
<pre>
gcc -o game game.c
</pre>
</p>
<p>
Nessun errore, nessun problema. Se non riuscite a compilarlo lavorateci
finch&eacute; non ci riuscirete.
</p>
<A NAME="229lfindex2">&nbsp;</A>
<H2>
<a name="precomp"> Pre-compilazione</a>
</H2>

<p>
Come fa il compilatore a sapere che tipo &egrave; <code>deck_t</code>?
Lo sa perch&eacute; durante la pre-compilazione copia il file
"deck.h" dentro il file "deck.c".
Le direttive del pre-compilatore nel codice sorgente iniziano con
"#". Potete richiamare il pre-compilatore tramite il front-end di
gcc con l'opzione <code>-E</code>.
<pre>
gcc -E -o game_precompile.txt game.c
wc -l game_precompile.txt
  3199 game_precompile.txt
</pre>
Quasi 3.200 linee di output! La maggior parte di queste vengono dall'include
<code>stdio.h</code> ma se ci guardate dentro ci trovere anche le
nostre dichiarazioni. Se non passate un nome di file con l'opzione
<code>-o</code> l'output verr&agrave; mandato in console. Il processo di
pre-compilazione d&agrave; maggior flessibilit&agrave; al codice eseguendo
tre compiti principali.
<ol>
<li>Copia i file "#include" nel sorgente che deve essere compilato.</li>
<li>Sistituisce i testi "#define" con il loro valore.</li>
<li>Sostituisce le macro col loro codice quando vengono chiamate.</li>
</ol>
Questo consente di avere costanti con un nome (per esempio DECKSIZE
rappresenta il numero di carte in un mazzo) usate in tutto il sorgente,
definite in un solo posto e aggiornate automaticamente dappertutto
non appena il valore cambia.
Normalmente non userete mai l'opzione <code>-E</code> da sola,
ma lascerete che passi il suo output al compilatore.
</p>
<A NAME="229lfindex3">&nbsp;</A>
<H2>
<a name="comp">Compilazione</a>
</H2>

<p>
Come passo intermedio, gcc trasforma il vostro codice in Assembly. Per farlo
deve capire cosa intendevate fare analizzando il vostro codice. Se avete
commesso degli errori di sintassi ve lo dir&agrave; e la compilazione fallir&agrave;.
Di solito la gente confonde questo passo con l'intero processo di
compilazione. Ma c'&egrave; ancora molto lavoro da fare per gcc.
</p>
<A NAME="229lfindex4">&nbsp;</A>
<H2>
<a name="assem">Assembly</a>
</H2>

<p>
<code>as</code> trasforma il codice Assembly in codice oggetto.
Il codice oggetto non pu&ograve; ancora essere lanciato sulla CPU, ma
ci si avvicina molto. L'opzione <code>-c</code> trasforma un file .c
in un file oggetto con estensione .o
Se lanciamo
<pre>
gcc -c game.c
</pre>
creiamo automaticamente un file che si chiama game.o
Qui siamo incappati in un punto importante. Possiamo prendere un
qualsiasi file .c e creare un file oggetto da esso. Come vedremo pi&ugrave; avanti
potremo combinare questi file oggetto in un eseguibile nella fase di Link.
Andiamo avanti col nostro esempio. Poich&eacute; stiamo programmando un gioco di carte
abbiamo definito un mazzo di carte come un <code>deck_t</code>, creeremo una
funziona per mischiare il mazzo.
Questa funzione prender&agrave; un puntatore a un tipo deck e lo riempie con delle
carte messe a caso. Tiene traccia di quali carte sono gi&agrave; state aggiunte
con l'array 'drawn'. Questo arraydi DECKSIZE elementi ci impedisce di duplicare
un valore di carta.
</p>
<pre>
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;
#include "deck.h"

static time_t seed = 0;

void shuffle(deck_t *pdeck)
{
  /* Tiene traccia di che numeri sono stati usati */
  int drawn[DECKSIZE] = {0};
  int i;

  /* Inizializzazione da fare una volta di rand */
  if(0 == seed)
  {
    seed = time(NULL);
    srand(seed);
  }
  for(i = 0; i < DECKSIZE; i++)
  {
    int value = -1;
    do
    {
      value = rand() % DECKSIZE;
    }
    while(drawn[value] != 0);

    /* segna il valore come usato */
    drawn[value] = 1;

    /* codice di debug */
    printf("%i\n", value);
    pdeck->card[i] = value;
  }
  pdeck->dealt = 0;
  return;
}
</pre>
<p>
Salvate questo file come <code>shuffle.c</code>.
Abbiamo inserito del codice di debug in questo codice in modo che,
quando viene lanciato, scriva i valori delle carte che genera.
Questo non aggiunge niente alle funzionalit&agrave; del programma, ma
&egrave; cruciale adesso che non possiamo vedere cosa succede.
Visto che stiamo appena cominciando il nostro gioco non abbiamo
altro modo di sapere se la nostra funzione fa quello che vogliamo.
Con il comando printf potete vedere esattamente cosa sta succedendo in
modo che quando passeremo alla prossima fase sapremo che il mazzo viene
mescolato bene. Dopo che saremmo soddisfatti del buon funzionamento
potremo togliere la linea dal nostro codice. Questa tecnica di debugging
pu&ograve; sembrare spartana, ma fa quello che deve fare con il minimo sforzo.
Discuteremo di debugger pi&ugrave; sofisticati in seguito.
</p>
Notate due cose.
<ol>
<li>
Passiamo il parametro per indirizzo, e lo si capisce dall'operatore
'&amp;' (indirizzo di). Questo passa l'indirizzo in memoria della
variabile alla funzione, in modo che la funzione possa cambiare la variabile
stessa. &Egrave; possibile programmare con variabili globali, ma dovrebbero essere
usate molto raramente. I puntatori sono una parte importante del C e
dovreste imparare a usarli molto bene.
</li>
<li>
Stiamo usando una chiamata a funzione da un nuovo file .c. Il Sistema
Operativo cerca sempre una funzione di nome 'main' e inizia l'esecuzione
da l&iacute;. <code>shuffle.c</code> non ha una funzione 'main' e quindi non pu&ograve;
essere trasformato in un eseguibile indipendente. Dobbiamo attaccarlo ad un
altro programma che abbia una 'main' e che chiami la funzione 'shuffle'.
</li>
</ol>
<p>
Lanciate il comando
<pre>
gcc -c shuffle.c
</pre>
e accertatevi che crei un nuovo file chiamato <code>shuffle.o</code>.
Editate il file game.c e, alla linea 7, dopo la dichiarazione della variabile
<code>deck</code> di tipo deck_t, aggiungete la linea
<pre>
shuffle(&amp;deck);
</pre>
Ora, se tenteremo di creare un eseguibile allo stesso modo di prima
otterremo un errore
<pre>
gcc -o game game.c

/tmp/ccmiHnJX.o: In function `main':
/tmp/ccmiHnJX.o(.text+0xf): undefined reference to `shuffle'
collect2: ld returned 1 exit status
</pre>
La compilazione &egrave; andata a buon fine perch&eacute; la sintassi
era corretta. La fase di link &egrave; fallita perch&eacute; non abbimo detto
al compilatore dove fosse la funzione 'shuffle'.
Cos'&egrave; la fase di <i>link</i> e come diciamo al compilatore
dove trovare questa funzione?
</p>
<A NAME="229lfindex5">&nbsp;</A>
<H2>
<a name="link">Link</a>
</H2>

<p>
Il linker, <code>ld</code>, prende il codice oggetto precedentemente
creato da <code>as</code> e lo trasforma in un eseguibile col comando
<pre>
gcc -o game game.o shuffle.o
</pre>
Questo unisce i due codici oggetto insieme e crea l'eeguibile
<code>game</code>.
</p>
<p>
Il linker trova la funzione <code>shuffle</code> nell'oggetto shuffle.o
e la include nell'eseguibile. La cosa veramente interessante dei file oggetto
&egrave; il fatto che se volessimo usare di nuovo quella funzione, tutto ci&ograve; che
dovremmo fare sarebbe includere il file "deck.h" e unire il file oggetto
<code>shuffle.o</code> nel nuovo file eseguibile.
</p>
<p>
Il riutilizzo di codice, come in questo caso, viene fatto spesso. Non
abbiamo scritto la funzione <code>printf</code> che abbiamo chiamato prima
come funzione di debug, il linker ha trovato la sua definizione nel file
che abbiamo incluso con <code>#include &lt;stdlib.h&gt;</code> e l'ha unita
al codice oggetto contenuto nella libreria C (/lib/libc.so.6).
In questo modo possiamo usare le funzioni di qualcun'altro, sapendo che
funzionano, e preoccuparci solo di risolvere i nostri problemi.
Questo &egrave; il motivo per cui i file header solitamente contengono solo
le definizioni delle funzioni e non il codice vero e proprio. Normalmente
si creano file oggetto o librerie che il linker metter&agrave; nell'eseguibile.
Un problema potrebbe sorgere con il nostro codice poich&eacute; non abbiamo messo
nessuna definizione di funzione nel nostro header. Cosa possiamo fare per
essere sicuri che tutto funzioni bene?
</p>
<A NAME="229lfindex6">&nbsp;</A>
<H2>
<a name="lasttwo">Altre Due Opzioni Importanti</a>
</H2>

<p>
L'opzione <code>-Wall</code> abilita tutti i tipi di avvertimenti
sulla sintassi del linguaggio per essere sicuri che il nostro codice
sia corretto e il pi&ugrave; portabile possibile. Quando usiamo questa opzione
e compiliamo il nostro codice vediamo qualcosa come:

<pre>
game.c:9: warning: implicit declaration of function `shuffle'
</pre>

Questo ci permette di sapere che abbiamo ancora un po' di lavoro da fare.
Dobbiamo aggiungere una linea al nostro header dove diamo al compilatore
tutte le informazionisulla nostra funzione <code>shuffle</code> in modo
che possa fare tutti i controlli di cui ha bisogno.
Sembra una difficolt&agrave; inutile, ma separa la definizione dall'implementazione
e ci permette di usare la nostra funzione dove vogliamo semplicemente
includendo il nostro nuovo header nel codice oggetto.
Metteremo questa riga nel file deck.h

<pre>
void shuffle(deck_t *pdeck);
</pre>
Questo ci liberer&agrave; del messaggio di avvertimento.
</p>
<p>
Un'altra opzione comune del compilatore &egrave; l'ottimizzazione
<code>-O#</code> (per esempio -O2).

Questo dice al compilatore il livello di ottimizzazione che vogliamo.
Il compilatore conosce un sacco di trucchi per far andare pi&ugrave; veloce il
nostro codice. Per un programma piccolo come il nostro non noterete alcuna
differenza, ma per programmi pi&ugrave; grandi potreste ottenere buoni aumenti
di velocit&agrave;. Lo vedete dappertutto, quindi dovreste sapere cosa significa.
</p>
<A NAME="229lfindex7">&nbsp;</A>
<H2>
<a name="debug">Debugging</a>
</H2>

<p>
Come sappiamo tutti, il fatto che il codice venga compilato non significa
che funzioni nel modo che vogliamo. Potete verificare che tutti i numeri
vengano usati una sola volta lanciando
<pre>
game | sort - n | less
</pre>
e controllando che non ne manchino. Cosa facciamo se c'&egrave; un problema?
Come troviamo l'errore?
</p>
Potete controllare il codice con un debugger. La maggior parte delle
distribuzioni rendono disponibile il classico gdb. Se la linea di
comando vi spaventa come lo fa a me, KDE offre una buona interfaccia
con <a href="http://members.nextra.at/johsixt/kdbg.html">KDbg</a>.
Ci sono anche altre interfacce, e sono molto simili. Per iniziare il
debugging, scegliete File-&gt;Executable e trovate il vostro programma
<code>game</code>.
Quando premete F5 o selezionate Execution-&gt;Run dal menu dovreste
vedere l'output su un'altra finestra. Cosa succede? Non vediamo niente
nella finestra. Non preoccupatevi, non &egrave; KDbg che non funziona. Il
problema nasce dal fatto che non abbiamo messo informazioni di debug
nel nostro codice eseguibile, quindi Kdbg non pu&ograve; dirci cosa sta
succedendo internamente. L'opzione del compilatore <code>-g</code>
inserisce le informazioni richieste nei file oggetto. Dovete compilare
i file oggetto (estensione .o) con questa opzione, quindi il comando
diventa
<pre>
gcc -g -c shuffle.c game.c
gcc -g -o game game.o shuffle.o
</pre>
Questo inserisce degli agganci nell'eseguibile per permettere a gdb e
KDbg di capire cosa sta succedendo. Il debugging &egrave; un'abilit&agrave; importante,
vale il tempo che dedicherete a imparare a usarla bene.
Il modo in cui i debugger aiutano i programmatori &egrave; la loro capacit&agrave; di
mettere dei 'Breakpoint' nel codice sorgente. Provate a inserirne uno
facendo click col tasto destro sulla linea che chiama la funzione
<code>shuffle</code>. Un piccolo cerchio rosso dovrebbe apparire vicino
alla riga. Ora, quando premete F5 il programma ferma la sua esecuzione a
quella linea. Premete F8 per entrare <i>dentro</i> la funzione shuffle.
Hey, ora state guardando il codice dentro <code>shuffle.c</code>!
Possiamo controllare l'esecuzione passo per passo e vedere cosa sta realmente
accadendo. Se passate il puntatore su una variabile locale potete vedere
cosa contiene. Carino. Molto meglio di quelle istruzioni <code>printf</code>, no?
</p>
<A NAME="229lfindex8">&nbsp;</A>
<H2>
Conclusioni
</H2>

<p>
Questo articolo si &egrave; presentato come un rapido giro sulla compilazione
e il debugging di programmi C. Abbiamo parlato dei passi che un compilatore
deve compiere e di quali opzioni passare a gcc per fargli fare tali passi.
Abbiamo accennato al linking di librerie condivise e abbiamo terminato con
una introduzione ai debugger.
Serve ancora un sacco di lavoro per sapere esattamente cosa state facendo,
ma spero che questo articolo vi sia servito per iniziare col piede giusto.
Potete trovare ulteriori informazioni nelle pagine <code>man</code> e
<code>info</code> di <code>gcc</code>, <code>as</code> e <code>ld</code>.
</p>
<p>
Scrivere codice da soli &egrave; la cosa migliore per imparare.
Per fare pratica, potreste prendere i frammenti di codice del gioco
di carte di questo articolo e scrivere un gioco di blackjack. Prendetevi
il tempo di imparare come funziona un debugger. &Egrave; molto pi&ugrave; semplice
partire con una interfaccia grafica come KDbg. Se aggiungerete poche
funzionalit&agrave; alla volta ne verrete fuori prima di quanto pensiate.
Ricordate di mantenerlo funzionante!
<p>
Queste sono alcune delle cose di cui avrete bisogno per fare un
gioco completo.
<ul>
<li> Una definizione di un giocatore (per esempio, potreste definire
deck_t come player_t).</li>
<li> Una funzione che dia un certo numero di carte a un giocatore. Ricordate
di incrementare il numero di carte date nel mazzo per tenere traccia di
dove prendere la prossima carta da dare.
Ricordate di terere traccia di quante carte ci sono in mano al giocatore.
</li>
<li> Un qualche tipo di interazione per chiedere al giocatore se vuole
un'altra carta.</li>
<li> Una funzione che stampi le carte del giocatore. La <i>carta</i>
&egrave; valore%13 (valori da 0 a 12), il <i>seme</i> &egrave; valore/13 (valori da 0 a 3)
</li>
<li> Una funzione per determinare il valore della mano del giocatore.
L'asso &egrave; la carta con numero 0 e pu&ograve; valere 1 o 11. I re hanno il numero
12 e valgono 10
</li>
</ul>
</p>
</p>
<A NAME="229lfindex9">&nbsp;</A>
<H2>
<a name="links">Links</a>
</H2>

<ul>
<li><a href="http://www.gnu.org/directory/gcc.html">gcc</a>
 GCC GNU Compiler Collection</li>
<li><a href="http://www.gnu.org/directory/gdb.html">gdb</a>
 GNU Debugger </li>
<li><a href="http://members.nextra.at/johsixt/kdbg.html">KDbg</a>
KDE's GUI Debugger
</li>
<li>
<a href="http://www.acm.org/classics/sep95">Award Winning Compiler Hack</a>
Ken Thompson's great compiler hack </li>
</ul>



<!-- vim: set sw=2 ts=2 et tw=74: -->

<!-- 2pdaIgnoreStart -->
<A NAME="talkback">&nbsp;</a>
<h2>Discussioni su quest'articolo</h2>
ogni articolo possiede una sua pagina di discussione, da questa pagina puoi inviare un commento o leggere quelli degli altri lettori:
<center>
<table border="0"  CELLSPACING="2" CELLPADDING="1">
 <tr BGCOLOR="#C2C2C2"><td align=center>
  <table border="3"  CELLSPACING="2" CELLPADDING="1">
   <tr BGCOLOR="#C2C2C2"><td align=center>
    <A href="http://cgi.linuxfocus.org/cgi-bin/lftalkback?anum=229&amp;lang=it"><b>&nbsp;pagina di discussione&nbsp;</b></a>
   </td></tr></table>
</td></tr></table>
</center>

<HR size="2" noshade>
<!-- ARTICLE FOOT -->
<CENTER><TABLE WIDTH="98%">
<TR><TD ALIGN=CENTER BGCOLOR="#9999AA" WIDTH="50%">
<A HREF="../../common/lfteam.html">Webpages maintained by the LinuxFocus Editor team</A>
<BR><FONT COLOR="#FFFFFF">&copy; Lorne Bailey, <a href="../../common/copy.html">FDL</a> <BR><a href="http://www.linuxfocus.org">LinuxFocus.org</a></FONT>
<BR><a href="http://cgi.linuxfocus.org/cgi-bin/lfcomment?lang=it&amp;article=article229.shtml" target="_TOP">Click here to report a fault or send a comment to LinuxFocus</A><BR></TD>
<TD BGCOLOR="#9999AA">
<!-- TRANSLATION INFO -->
<font size=2>Translation information:</font>
<TABLE>
  <tr><td><font size="2">en --&gt; -- : Lorne Bailey <small>&lt;sherm_pbody(at)yahoo.com&gt;</small></font></td></tr>
  <tr><td><font size="2">en --&gt; it: Alessandro Pellizzari &lt;alex(at)neko.it&gt;</font></td></tr>
</TABLE>
</TD>
</TR></TABLE></CENTER>
<p><font size=1>2002-02-28, generated by lfparser version 2.25</font></p>
<!-- 2pdaIgnoreStop -->
</BODY>
</HTML>