Newsgroup: it.comp.lang.c++
Titolo: [?]:extern

Ciao a tutti,
sto studiando da pochissimo il C++, per esercizio sto scrivendo il seguente
codice:
#include <pow.cpp>
#include <iostream>
int main(){
    int base=2, potenza=15;
    cout << "Le potenze di 2\n";
    for(int cnt=0; cnt<=potenza; ++cnt)
        cout << cnt << ": " << pow(base,cnt) << endl;
    return 0;
}
dove il file pow.cpp contiene il segunete codice:
int pow(int val, int exp)
{
    int res=1;
    for (int cnt=exp; cnt>0;--cnt)
        res = res * val;
    return res;
}
Compilo il tutto e funziona tutto, ma non capisco se tolgo la linea con:
extern int pow(int,int);
io mi aspetterei un errore, in quanto nella main la funzione pow non č stata
dichiarata e dunque allocata.
Possibile che sia dovuto dalle impostazioni del mio compilatore. Il
compilatore che uso io č Dev-C++ (4.9.3.0)
Oppure sono io che non ho compreso qualcosa?
Grazie a tutti.
Deckard

 ha scritto nel messaggio
news:fE5N8.27356$5i1.1...@news2.tin.it...


 Francesco!
Beh, accade anche se il codice lo scrivo esplicitamente... beh, forse sono
io che non ho ben capito l'utilizzo di extern.
Insomma extern dovrebbe servire a dichiarare al programma che la definizione
di un oggetto è stata già fatta, ma da un'altra parte del programma.
Sbaglio? Allora se ometto la extern, la main dovrebbe segnalarmi che
all'interno di essa l'oggeto (la funzione) non è stata dichiartata.
Grazie ancora
Deckard

 ha scritto nel messaggio
news:iM6N8.27667$5i1.1...@news2.tin.it...


 dichiarata e dunque allocata.
Lo specificatore extern serve ad utilizzare una variabile globale definita
in un altro modulo. Quanto in un file *.cpp dichiari una variabile globale,
questa ha visibilità solo al file in cui è dichiarata, per cui se vuoi che
possa essere vista anche da un altro file devi dichiararla come extern. Per
le funzioni non vale, in quanto per usare una funzione che è definita in un
altro file basta ridefinire il prototipo di quella funzione (cosa che viene
fatta quando si usa la direttiva #include ) e poi linkare il file con quello
in cui è contenuto il codice.
Spero di essere stato chiaro,
--
ciao,
Cecco
---------
Visit: 
www.sourceforge.net/projects/dlab
Home Page: 
http://dlab.sourceforge.net/
Dlab-developer mailing list
https://lists.sourceforge.net/lists/listinfo/dlab-developer

 stata dichiarata e dunque allocata.
ti sbagli; quando tu includi "pow.cpp" il compilatore vede la funzione 
pow come se fosse stata scritta prima del main; in pratica e` come se 
scrivessi:
int pow(......)
{
        ....
}
int main()
{
        ....
}
Ovviamente questo codice funziona correttamente perche` il compilatore 
considera la definizione di int pow come se fosse anche una 
dichiarazione.
In ogni caso quello da te proposto non e` il modo corretto di procedere: 
dovresti creare un header pow.h nel quale scrivi il prototipo della 
funzione
        extern int pow(); // extern e` opzionale
e poi #includere l'header, non il .cpp.
Ovviamente affinche` tutto funzioni devi anche dire al compilatore di 
compilare il file pow.cpp assieme al tuo sorgente principale: purtroppo 
non posso essere piu` preciso perche` questo dipende dal tuo 
compilatore.
ciao Anto
-- 
Antonio Cuni, 20 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it


Grazie a tutti per le risposte e le indicazioni, penso di avere più chiare
le idee adesso. Ma alcuni dubbi rimangono.
Da quanto ho capito extern effettua una dichiarazione (quindi senza fare una
definizione: allocazione di memoria) avvertendo il programma che la
definizione di una variabile (o un oggetto, più in generale) è fatta da
qualche altra parte. In particolare, se compilo un programma al quale faccio
un link di un file oggetto contenente la suddetta variabile.
OK, teoricamente mi sembra di aver capito, ma da profano non capisco il
reale utilizzo; proverò a spiegarmi.
Se ho capito bene, in fase di sviluppo dovrò aver ben chiaro quali variabili
o funzioni sono dichiarate nel file oggetto, mi domando se questo possa
essere sempre possibile? E se non posssa essere un dispendio di tempo in
più. Inoltre, immagino che le variabili definite nel file oggetto siano
dichiarate in ambito globale, altrimenti come posso accedervi? Quindi mi
viene spontanea la domanda: come deve essere la morfologia corretta di
suddetto codice?
E in più, non mi è chiario allora quando tendere all'utilizzo di header o a
"linkare" un file oggetto.
Chiedo scusa per le eventuali ovvietà espresse o cantonate, ma vorrete
perdonare le domante di un neofita.
Grazie a tutti.
Deckard

 o a "linkare" un file oggetto.
non avevo capito molto il senso delle tue domande ma leggendo questa 
frase 
penso che sia perche` ti sei un po' confuso.
L'uso dei file header ha senso proprio quando abbiamo dei file oggetto da 
linkare al nostro sorgente; supponiamo di avere questo file:
--- prova.c ---
int global;
void f() { ... }
-----------------
se compiliamo questo file otteniamo un file oggetto (ad esempio prova.o) 
che 
contiene la definizione della variabile "global" e della funzione "f".
Ora supponi di voler linkare il file oggetto cosi` ottenuto con un file 
che 
contiene il tuo main:
--- main.c ---
int main()
{
        global = 10;
        f();
}
---------------
Ovviamente questo non funzionera` mai: il compilatore dara` errore 
poiche` ne` 
global ne` f sono nomi definiti; proviamo di nuovo:
--- main.c ---
int global;
void f() { ... }
int main()
{
        global = 10;
        f();
}
---------------
Ancora una volta non funziona: il compilatore compila correttamente il 
sorgente e produce un file oggetto che contiene le definizioni della 
variabile "global" e delle funzioni "f" e "main": purtroppo quando il 
linker cerca di collegare assieme i due file di oggetto (main.o e 
prova.o) va in errore: infatti entrambi i file contengono le definizioni 
di "global" e "f" e il linker "non sa quale scegliere".
Dobbiamo trovare un'altra strada: la soluzione sta nel dire al 
compilatore "guarda, se nel codice trovi 'global' sappi che e` una 
variabile globale di tipo int, ma non allocare memoria per essa: la 
memoria e` gia` allocata in un altro file oggetto" (stesso discorso per 
la funzione "f"): per far capire questo al compilatore dobbiamo 
*dichiarare* che global ed f esistono:
        extern int global;
        extern void f();
Nota che, a differenza delle variabili, la keyword "extern" e` 
facoltativa quando dichiariamo una funzione: per cui le prossime due 
righe sono esattamente equivalenti alle precedenti due:
        extern int global;
        void f();
A questo punto siamo quasi alla fine:
--- main.c ---
extern int global;
void f();
int main()
{
        global = 10;
        f();
}
---------------
Se compiliamo questo sorgente e lo linkiamo al file prova.o otteniamo un 
eseguibile valido (finalmente! ;-).
Pero` questa non e` la soluzione migliore: immagina di avere un file 
oggetto che contiene una grossa libreria (decine o centiaia di funzioni 
e variabili) e di usare questa libreria in molti sorgenti: ogni volta 
che usi una funzione dovresti scriverti a mano la corrispondente 
dichiarazione: a lungo andare questo diventa noioso e soggetto ad errori 
(pensa se ti sbagli e scrivi "int f()" anziche` "void f()": il tuo 
programma crashera` misteriosamente), quindi la soluzione che si usa 
comunemente e` quella dei file header: si raggruppano tutte le 
dichiarazioni relative ad un file oggetto in un unico file .h e ogni 
volta che si devono usare quelle funzioni si #include il file 
all'interno del sorgente; quindi la soluzione finale sarebbe questa:
--- prova.h ---
extern int global;
void f();
-------------------
--- main.c ---
#include "prova.h"
int main()
{
        global = 10;
        f();
}
---------------
spero di essere stato chiaro
