View Full Version : [C] undefined reference
salve a tutti,
allora, ho un progetto con due file .h e un file .c (con il main):
- prototipi delle funzioni nel file primo.h
- implementazioni delle funzioni del file primo.h nel file secondo.h
- inclusione dei due file .h nel file .c dove c'e il main ecc
quando compilo non ci sono errori, ma quando interviene il linker (giusto?) mi da [LINKER ERROR]undefined reference a tutte le funzioni che io ho dichiarato e implementato.
dove sto sbagliando:(
Daniels118
13-02-2014, 15:30
I prototipi delle funzioni vanno bene nel file .h, ma l'implementazione va nei file .c. Comincia a correggere, se hai ancora problemi scrivi i messaggi di errore esatti.
I prototipi delle funzioni vanno bene nel file .h, ma l'implementazione va nei file .c. Comincia a correggere, se hai ancora problemi scrivi i messaggi di errore esatti.
a questo punto pero devo creare un makefile è giusto?
oppure posso includere il file con le implementazioni delle funzioni (secondo.c) direttamente nel main.c con #include "secondo.c"
perchè non mi è mai capitato di usare due file .c nello stesso progetto :(
Daniels118
13-02-2014, 15:43
Si, puoi mettere tutto nel main, comunque non è necessario creare il makefile, il compilatore dovrebbe poter compilare più file in un colpo solo, consulta l'help del tuo compilatore per vedere qual'è la sintassi.
daniels ho provato ad includere il file con #include "secondo.c" (si trova nella stessa cartella del main.c) ma da ancora gli stessi errori di undefined reference.
il compilatore è gcc però per un particolare progetto di sistemi operativi.
a questo punto l'unica alternativa è studiarmi come si crea un makefile giusto? (beh alla fine avrei dovuto impararlo :muro: )
p.s.
considerando che il main.c si appoggia su funzioni che stanno nel file secondo.c i cui prototipi stanno in primo.h, qual'è diciamo l'albero delle dipendenze (sto guardando un po di guide e questa cosa ancora mi è sfuggita)
chi ha più priorità nella compilazione?
Daniels118
13-02-2014, 16:10
I file .c non vanno inclusi, ma compilati, e i risultati della compilazione (.o) vanno linkati insieme nell'eseguibile.
Non è che non si possano includere i file .c, ma tra regole e convenzioni si rischia di fare un casino, cerchiamo di parlare tutti la stessa lingua :)
Daniels118
13-02-2014, 16:16
Ho visto ora che hai aggiornato la risposta...
non è una questione di priorità, i file .c possono essere compilati in modo del tutto indipendente tra loro. Se una funzione F definita nel file A viene richiamata nel file B, è sufficiente che B includa l'header dove c'è il prototipo di F. L'header non deve contenere né variabili né istruzioni, ma solo direttive e definizioni, così può essere incluso in più file .c senza che in fase di link si ci ritrovi con codice o dati duplicati.
non ci sto capendo piu nulla, questa parte mi sembra difficile anche se immagino che in realtà sia facilissimo.
ho capito che:
compilo A.c facendolo diventare A.o
compilo B.c facendolo diventare B.o
ho guardato delle guide sui makefile ma ciò che trovo sono tutti argomenti sulle dipendenze, ma come faccio a linkare A.o a B.o?:cry:
p.s. esiste l'estensione .e?
lorenzo001
13-02-2014, 20:35
Non includere i file.c ...
Scrivi
gcc -o eseguibile main.c file1.c file2.c
Non includere i file.c ...
Scrivi
gcc -o eseguibile main.c file1.c file2.c
per compilare di solito usavo scrivere
gcc -c -o eseguibile file.c (non so pero cosa significhi il comando -c)
il tuo comando mi continua a dare errori di undefined reference.:cry:
provo a spiegare meglio il progetto come è costruito:
main.c - inclusioni di const.h, funzioni.h
const.h - costanti (nessuna inclusione)
funzioni.h - definizioni delle strutture e dei prototipi delle funzioni (nessuna inclusione)
funzioni.c - implementazione delle funzioni con le strutture e le costanti (nessuna inclusione)
il problema è che sto provando in mille modi ma non capisco come compilare il tutto senza darmi errori di [LINKER ERROR] undefined reference funzione pippo, [LINKER ERROR] undefined reference funzione pluto,..... .
come devo procedere passo per passo per far si che compili :muro: :cry: :cry: :muro: :muro: :muro: ?
clockover
14-02-2014, 12:15
Esempio molto idiota
File --> fact.c
int fattoriale(int value){
if(value <= 0)return 1;
if(value == 2)return 2;
int tmp = value--;
while(value > 1)tmp *= value--;
return tmp;
}
File --> main.c
#include "head.h"
int main(int argn, char ** argp){
int value = 8;
printf("Il fattoriale di %d è %d\n", value, fattoriale(value));
return 0;
}
File --> head.h
#include <stdio.h>
#include <stdlib.h>
int fattoriale(int);
Compilazione:
1) gcc -o eseguibile main.c fact.c
oppure
2) gcc -c main.c fact.c / oppure gcc -c *.c
gcc -o eseguibile main.o fact.o / oppure gcc -o eseguibile *.o
Quando esegui gcc -c crei soltanto i files oggetto (estensione .o) e non esegui il linker. Se ometti -c crei file oggetto e richiami anche il linker.
Dai uno sguardo qui --> http://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html
Trucco numero 1 per capirci qualcosa: fai prove stupide e semplici come quella che ti ho fatto vedere io qui sopra.
Quando tu mi scrivi
"per compilare di solito usavo scrivere
gcc -c -o eseguibile file.c (non so pero cosa significhi il comando -c)"
vuol dire che stai digitando comandi a memoria e senza capire... fai prove stupide e semplici e piano piano farai bene progetti più grandi... :)
Daniels118
14-02-2014, 12:30
Nel file funzioni funzioni.c devi includere funzioni.h. Per spiegarti il perchè ti faccio un semplice esempio:
void A() {
B();
}
void B() {
...
}
In questo caso viene generato un errore di compilazione perché il compilatore vede una chiamata a B, ma questa non è stata ancora definita.
Comunque non è quello il problema, perché l'errore non viene generato nella fase di compilazione, ma in quella di link, e ciò significa che la funzione "undefined" non si trova in nessuno dei file che stai linkando insieme.
Ti ricordo inoltre che il c è case sensitive, "pluto" è diverso da "Pluto".
Compilazione:
1) gcc -o eseguibile main.c fact.c
oppure
2) gcc -c main.c fact.c / oppure gcc -c *.c
gcc -o eseguibile main.o fact.o / oppure gcc -o eseguibile *.o
grazie mille per la risposta clock.
penso di aver capito la tua spiegazione, ma quando lancio il comando
gcc -c main.c funzioni.c
il programma mi da errore, perche non mi riconosce le strutture (in funzioni.h) e le costanti (const.h) nel file funzioni.c
:cry:
Nel file funzioni funzioni.c devi includere funzioni.h. Per spiegarti il perchè ti faccio un semplice esempio:
void A() {
B();
}
void B() {
...
}
In questo caso viene generato un errore di compilazione perché il compilatore vede una chiamata a B, ma questa non è stata ancora definita.
Comunque non è quello il problema, perché l'errore non viene generato nella fase di compilazione, ma in quella di link, e ciò significa che la funzione "undefined" non si trova in nessuno dei file che stai linkando insieme.
Ti ricordo inoltre che il c è case sensitive, "pluto" è diverso da "Pluto".
ho incluso funzioni.h e anche const.h e ora funziona bene, mi ha creato 2 file oggetto.
ora come devo fare per linkarli?
Daniels118
14-02-2014, 12:41
EDIT:
Possiamo avere l'onore di vedere il tuo programma top-secreet? :p
Come ha detto clockover:
gcc -o eseguibile.exe main.o funzioni.o
Possiamo avere l'onore di vedere il tuo programma top-secreet? :p
sarebbe lunghissimo, perche in realtà io l'ho semplificato moltissimo, posso contattarti in privato per mostrartelo?
risolto!
bisogna usare il comando LD
clockover
14-02-2014, 16:20
risolto!
bisogna usare il comando LD
In realtà gcc utilizza proprio ld
Inviato da una supercazzola ed un Nexus 5 scappellato a sinistra.. con senso unico
Daniels118
14-02-2014, 16:49
Misteri del G-C-C... :D
lorenzo001
14-02-2014, 17:35
risolto!
bisogna usare il comando LD
Ti avevo detto di usare
gcc -o eseguibile file1.c file2.c
che eseguiva anche il linker ma non l'hai fatto.
Hai voluto generare solo i file oggetto con
gcc -c ...
per poi scoprire, entusiasta, che non eseguiva il linker che potevi eseguire a parte ...
Ma seguire il primo consiglio che ti avevo dato, no ?
Ti avevo detto di usare
gcc -o eseguibile file1.c file2.c
che eseguiva anche il linker ma non l'hai fatto.
Hai voluto generare solo i file oggetto con
gcc -c ...
per poi scoprire, entusiasta, che non eseguiva il linker che potevi eseguire a parte ...
Ma seguire il primo consiglio che ti avevo dato, no ?
credimi l'ho fatto, ma ho commesso un gravissimo errore omettendo il fatto che dovevo linkare quei sorgenti anche a più librerie di sistema, e per farlo dovevo usare il comando LD .
i vostri aiuti mi sono stati di enorme aiuto perche senza di voi non avrei capito bene come funziona la compilazione e il linking con gcc
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.