Newsgroup: it.comp.os.linux.development
Titolo: primi passi con il linker g++

ciao a tutti, ho da poco iniziato a fare i primi passi con la
programmazione su ambiente linux. per prima cosa ho iniziato a scrivere
alcuni file per poi compilarli. i file sono 3: a.cpp,che contiene il main,
b.h e b.cpp.
la dipendenza dei file è questa: a.cpp include b.h e b.cpp include b.h.
se non sbaglio i passi per ottenere un eseguibile sono: 
1) compilazione: g++ -c a.cpp b.cpp
2) linking: g++ -o a a.o b.o
il mio problema è che ora il linker mi da il seguente errore: "multiple
definition of ..." ed è relativo ad una funzione utlizzata in a.cpp,
definita in b.cpp ed il cui prototipo è in b.h. 
nel file b.h in testa ho inserito:
#ifndef _BH_
#define _BH
...
resto del codice e dichiarazione di prototipi di funzioni
...
#endif
pensando di risolvere il problema. ma evidentemente non è la giusta
strada.
scusate se la domanda vi sembra banale ma non conosco persone che hanno
queste competenze ed il newsgroup mi è sembrato un buo modo per chiedere
chiarimenti
Grazie
   Alessio

    Alessio
Ciao
M`

Immagino che lo stesso discorso vale per la dichiarazione di
variabili globali, giusto? Non posso, nel mio file .h, inserire questa
riga: 
...
int miavar;
...
senza incorrere nel solito errore del linker. Ho fatto una prova e mi
sembra essere proprio cosi.
Lo logica con cui lavora il linker mi sembra corretta: se una variabile
con lo stesso nome esiste già nello stesso scope, una seconda
dichiarazione sarebbe ambigua. C'è però una cosa che non capisco: in
testa al mio file .h ho inserito un #ifndef che dovrebbe impedire che
venga processato due volte del compilatore. E' corretto?
Grazie
   Alessio


    Alessio
Presupposto che ogni file viene compilato a parte. Supponi di aver
inserito la dichiarazione di una struttura in un file pippo.h. Il file
pluto.h usa questa struttura e per questa ragione include pippo.h. Ora
stai compilando il file pippo.c che include sia pippo.h che pluto.h; Cosa
succede se non inserisci #ifndef.. ? Succede che pippo.h viene incluso due
volte nella stessa compilazione di pippo.c e il compilatore ti informerà
che ha trovato due volte la definizione di una struttura con lo stesso
nome (errore). Ecco a che serve l'#ifndef.. :) La prima volta che pippo.h
viene processato il preprocessore definisce una variabile(?) (con #define)
in modo tale che la seconda volta che analizza il file salta l'intero
blocco #ifndef..#endif.
btw uno stesso file.h può essere (e spesso è) incluso da più file.c.
Per questo motivo non si può dichiarare niente che abbia una
corrispondenza col codice prodotto (corpo di funzioni o variabili che
siano), altrimenti due file oggetto (risultanti da due diverse
compilazioni di file.c che includevano lo stesso file.h) si ritrovano ad
avere la stessa variabile definita ognuno per conto suo, o la stessa
funzione.
La soluzione è quella di dichiarare il corpo di una funzione in un file.c
e dichiararne soltanto il prototipo nel corrispondente file.h; per quanto
riguarda le variabili globali si fa la stessa cosa: si dichiara la
variabile una sola volta in un solo file.c, e se è globale a più file,
la si dichiara extern nel corrispondente file.h.
In questo modo, un secondo file2.c che include file.h SA che esiste una
funzione che ha quel prototipo e anche se non ne conosce il codice la puo
utilizzare ed essere compilato correttamente (il compilatore sa che ci
penserà il linker dopo a collegare la chiamata al codice vero e proprio);
similarmente il file2.c SA che esiste una variabile globale (avendone
letta la dichiarazione extern) e anche se non sa di preciso dove è
dichiarata lascerà al linker il compito di sostituire quello che lui
scrive "temporaneamente" nel file oggetto con il riferimento corretto.
Ciao
Matic

> int miavar;
Nell'header, "extern int miavar;".
Comunque se ti si dà errore di linking significa che stai definendo
qualcosa due volte in uno dei due file di implementazione, oppure che
stai definendo qualcosa nel file di header.
Ciao,
-- 
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
------END GEEK CODE BLOCK------