View Full Version : [c] stranissimo problema con #ifndef
ho un problema assurdo: in un header (e sottolineo solo in uno su tutti quelli che compongono il programma) se faccio così
#ifndef _HEADER_
#define _HEADER_
#endif
il compilatore (gcc sotto cygwin) mi dice che ci sono delle definizioni multiple dei dati. non riuscendo a venire a capo al problema, ho provato a fare
#ifdef _HEADER_
#define _HEADER_
#endif
e la compilazione è andata a buon fine :mbe:
in tutti gli altri header utilizzo ifndef e va tutto come deve andare, solo su questo ho questo stranissimo problema..
sottovento
27-08-2008, 17:14
Hai provato anche ad usare un nome diverso da _HEADER_?
Hai provato anche ad usare un nome diverso da _HEADER_?
si, _HEADER_ l'ho messo solo lì sopra come esempio.
comunque ho provato anche a compilare sotto gnu\linux e fa uguale
A parte che #define _HEADER_ non ha senso in quel caso perchè è già definito, non ci hai dato abbastanza informazioni.
Dovresti perlomeno incollare il segmento di codice e l'errore del compilatore, eventualmente tutto il codice se non è troppo lungo/troppo personale.
Posta così vediamo un po' ;)
A parte che #define _HEADER_ non ha senso in quel caso perchè è già definito, non ci hai dato abbastanza informazioni.
Dovresti perlomeno incollare il segmento di codice e l'errore del compilatore, eventualmente tutto il codice se non è troppo lungo/troppo personale.
Posta così vediamo un po' ;)
header incriminato:
#ifndef _COUNT_WORDS_
#define _COUNT_WORDS_
char* ultimo_blocco_words=NULL;
char* StaccaBlocco(char* blocco, int lunghezza);
char* AttaccaBlocco(char* blocco, int lunghezza);
#endif
altro header, funzionante con #ifndef:
#ifndef _UTILS_
#define _UTILS_
char Complemento_A_2(char input);
int Controllo_Segno(char input);
int ControlloEstensione(char* input);
#endif
errore:
count_words.o: In function `StaccaBlocco':
/cygdrive/c/progetto/count_words.c:8: multiple definition of `_ultimo_blocco_words'
main.o:/cygdrive/c/progetto/main.c:13: first defined here
collect2: ld returned 1 exit status
make: *** [LabProg] Error 1
nel main ho incluso l'header incriminato.
edit: il problema sembra essere "char* ultimo_blocco_words=NULL;" visto che togliendolo va tutto, ma non capisco perchè visto che la seconda volta dovrebbe saltare tutto il blocco a causa dell'ifndef
wizard1993
27-08-2008, 18:54
forse ti può essere utile vedere l'uso della direttiva #pragma once
non la supportava solo il compilatore micorsoft?
Il problema è che così facendo definisci una variabile in 2 file :D
Devi rimuoverla dall'header e definirla solo nel file che ne farà effettivamente uso, e usare eventualmente la keyword extern.
Nell'header puoi inserire solo dichiarazioni ;)
In ogni caso #pragma once dovrebbe andare anche con gcc.
Il problema è che così facendo definisci una variabile in 2 file :D
Devi rimuoverla dall'header e definirla solo nel file che ne farà effettivamente uso, e usare eventualmente la keyword extern.
Nell'header puoi inserire solo dichiarazioni ;)
In ogni caso #pragma once dovrebbe andare anche con gcc.
intanto ti ringrazio ma ho un paio di domande, perchè la situazione non mi è molto chiara :D :
-ma come mai con ifdef funzionava? :confused: e perchè anche la seconda volta entrava nel controllo, ridefinendola un'altra volta?
-ma se gli header si utilizzano tramite la direttiva #include, che non fa altro che sostituire il contenuto dell'header nel punto in cui è stata utilizzata, perchè c'è questo "limite" di poter inserire solo dichiarazioni?
vi ringrazio in anticipo per le risposte :)
sottovento
28-08-2008, 08:00
header incriminato:
#ifndef _COUNT_WORDS_
#define _COUNT_WORDS_
char* ultimo_blocco_words=NULL;
char* StaccaBlocco(char* blocco, int lunghezza);
char* AttaccaBlocco(char* blocco, int lunghezza);
#endif
altro header, funzionante con #ifndef:
#ifndef _UTILS_
#define _UTILS_
char Complemento_A_2(char input);
int Controllo_Segno(char input);
int ControlloEstensione(char* input);
#endif
errore:
count_words.o: In function `StaccaBlocco':
/cygdrive/c/progetto/count_words.c:8: multiple definition of `_ultimo_blocco_words'
main.o:/cygdrive/c/progetto/main.c:13: first defined here
collect2: ld returned 1 exit status
make: *** [LabProg] Error 1
nel main ho incluso l'header incriminato.
edit: il problema sembra essere "char* ultimo_blocco_words=NULL;" visto che togliendolo va tutto, ma non capisco perchè visto che la seconda volta dovrebbe saltare tutto il blocco a causa dell'ifndef
Eh no! Nel primo caso vai davvero a definire due volte la stessa variabile globale, in due file diverse e quindi il compilatore ha tutte le ragioni di arrabbiarsi.
I due casi che hai presentato sono totalmente diversi: nel primo vai a definire una variabile globale (chiamata ultimo_blocco_words), nel caso in cui ti funziona tutto vai semplicemente a definire dei prototipi di funzione (fra l'altro non ti darebbero problemi nemmeno se togli le direttive di compilazione).
La variabile ultimo_blocco_words la devi definire in un unico punto.
Quello che normalmente viene fatto e' mettere un extern nel file di intestazione:
#ifndef _COUNT_WORDS_
#define _COUNT_WORDS_
extern char* ultimo_blocco_words;
char* StaccaBlocco(char* blocco, int lunghezza);
char* AttaccaBlocco(char* blocco, int lunghezza);
#endif
ed in un file .c o .cpp (tipicamente quello contenente il main, oppure un file chiamato global.cpp o come meglio preferisci) definisci
char* ultimo_blocco_words=NULL;
Ci sono altre soluzioni, ovviamente...
Comunque valuta sempre se puoi evitare l'uso di variabili globali
DanieleC88
28-08-2008, 11:58
In ogni caso #pragma once dovrebbe andare anche con gcc.
Potrebbe essere supportato, ma non l'ho provato. In ogni caso, non è standard, quindi si fa bene ad evitarlo quando possibile. :)
Comunque valuta sempre se puoi evitare l'uso di variabili globali
Quotissimo. :mano:
In ogni caso, nella seconda variante con #ifdef invece di #ifndef mi sa che non hai definito un bel niente, quando invece nella prima versione l'hai definita due volte in due file diversi (e in fase di linking GCC ovviamente s'incazza). Prova a toglierla di mezzo: se deve essere privata definiscila static e solo in un file, al limite.
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.