2015-09-27 2 views
-3

У меня есть несколько файлов .h/.cpp, каждый из которых должен иметь файлы, называемые «common.h/common.cpp», поскольку я повторно использую его определения в остальной части мои файлы. Файл common.h определяет некоторые намеренно глобальные переменные.gcc/g ++ и несколько определений глобальных переменных

Я работаю под Linux и gcc 4.4.7.

Compuler делает работу ОК, но г ++ компоновщик жалуется на многие случаи, как:

build/Debug/GNU-Linux-x86/StoreData2/spacewx.o:(.data+0x200): multiple definition of `nmdata::names` 
build/Debug/GNU-Linux-x86/StoreData2/StoreData2.o:(.data+0x200): first defined here 

и как таковой я не получаю Преуспевающие сборки. Пожалуйста, совет, как избавиться от этой ошибки и сохранить эти глобальные переменные. Я использую только функциональное программирование (используя библиотеки C++, такие как boost), а также собственные пространства имен/объекты.

+3

Где вы, минимальный пример? –

+0

Вы действительно не думали, что какая-либо из исходных червей может быть актуальной? –

+0

Рассмотрите возможность использования ключевого слова 'extern'. Если вы можете дать нам минимальный код, я могу дать вам хороший ответ. –

ответ

3

Давайте предположим, что ваш глобальный заголовок (global.h):

#ifndef _GLOBAL_H 
#define _GLOBAL_H 

int g_a; 

#endif 

Если у вас есть два исходных файлов, включая global.h: a.cpp и b.cpp, как это:

a.cpp

#include "global.h" 
/* some source */ 

b.cpp

#include "global.h" 
/* some source */ 

После предварительной обработки они будут выглядеть следующим образом (включаемые файлы расширен):

a.cpp

int g_a; 
/* some source */ 

b.cpp

int g_a; 
/* some source */ 

Так что, если вы собираете эти исходные файлы, глобальная переменная int g_a будет определяться в двух объектных файлах. Поэтому компоновщик будет жаловаться на несколько определений.

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

Изменение global.h следующим образом:

#ifndef _GLOBAL_H 
#define _GLOBAL_H 

extern int g_a; 

#endif 

Таким образом, не будет никакого int g_a запись не будет записана в объектные файлы. Но это приведет к ошибке неопределенного символа при связывании. Чтобы преодолеть это, определите int g_a в a.cpp или b.cpp, но не в обоих.

b.cpp

#include "global.h" 
int g_a; 
/* some source */ 
1

Каждая переменная или функция в вашей программе может быть только определен один раз, в одном compiliation устройстве.Если вы определите что-нибудь в нескольких единицах компиляции, вы, как правило, получите сообщение об ошибке, как вы видите, хотя официально это неопределенное поведение, поэтому компилятор может не дать диагностику, и ваша программа будет просто ошибочной.

Вы можете иметь несколько деклараций вещей в вашей программе, так что в целом установить вещи так, что ваши файлы головы имеют ТОЛЬКО заявления со всеми определениями в .cpp файлах.

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