2013-10-25 3 views
0

Я получаю следующие ошибки, когда пытаюсь построить мои файлы кода c с -D. Но, если я построю его без -D, он работает. Я не знаю почему. Благодарю. (Моя машина ubuntu12.10, 32bit)Ошибка при создании кода c с -D

gcc c1.c c2.c -D DEBUG 

/tmp/ccX04EIf.o:(.data+0x0): multiple definition of `g' 
/tmp/cc0j9MoU.o:(.data+0x0): first defined here 
collect2: ld returned 1 exit status 

Вот мой исходный код:

global.h

#ifdef DEBUG 
    int g = 23; 
    static int init = 1; 
#else 
    int g; 
    static int init = 0; 
#endif 

c1.c

#include "global.h" 
int f() { 
    return g + 1; 
} 

c2.c

#include <stdio.h> 
#include "global.h" 

int main() { 
    if (!init) { 
     g = 37; 
    } 
    int t = f(); 
    printf("calling f yields %d\n", t); 

    return 0; 
} 
+0

Почему пространство между '-D' и' DEBUG'? –

+0

@HowChen Это имеет значение? № – RedX

+0

@ Просто, но он сказал, что это работает без -D –

ответ

3

Вы определить переменная g в файле заголовка, это означает, что она будет определена во всех исходных файлах, которые включают заголовочный файл.

Вместо объявить это, как

extern int g; 

, а затем определить его в одном исходном файле.

+0

или добавить включить охранники? –

+0

@HowChen Включить защитные ограждения защищает только от множественного включения в единую единицу перевода (например, исходный файл), а не против множественного включения в несколько единиц перевода. –

+0

@JoachimPileborg Я понимаю, что вы имеете в виду. Теперь я изменяю global.h, чтобы убедиться, что есть только объявление g и переместить определение g в c2.c, когда определено DEBUG. Оно работает. Спасибо. – qiaoba

1

Разница между двумя кодами (с и без DEBUG) является инициализацией переменной g. Без него это всего лишь «предварительное» определение, поэтому символ генерируется только в файле, который его действительно использует, а именно c2.o.

С инициализацией это реальное определение символа, и поэтому оно также генерируется в c1.o.

Как правило, заголовочные файлы никогда не должны содержать определения данных, только декларации. Данные «только объявления» должны быть сделаны с ключевым словом extern. Затем вам нужно будет определить любой такой символ в одном из ваших .c файлов.

Смежные вопросы