Мы пытаемся скомпилировать программу на компьютере серии Tandem X, но мы получаем ошибки в форме «Недопустимое дублирование определения инициализированного элемента данных в C и / или C ++». Тот же код успешно скомпилирован для нас на машине серии aTandem S.
У нас есть следующая структура файла:
/—AddressMap.h—-/
#ifndef ADDRESSMAP // Header file macro
#define ADDRESSMAP // Header file macro
typedef map<long,char*,less<long> > gAddress; data type
gAddress::iterator gAddressIterator; // define iterator
gAddress gAddressMap; // define variable
#endif//ADDRESSMAP
/*file1.cpp: -> Первый файл с использованием AddressMap * /
#include "AddressMap.h" // include file
/*file2.cpp: -> Второй файл, также использующий AddressMap * /
#include "AddressMap.h" // include file
проблема
Оба файла успешно скомпилированы, но связать их вместе невозможно …
Недопустимое дублирование определения инициализированного элемента данных gAddressMap
в file1.o и в file2.o
Поскольку оба файла должны иметь доступ к этой переменной, оба включили файл заголовка; может быть, это ответственно за ошибку. Кроме того, это существующий код, поэтому мы хотим избежать серьезных изменений кода. В частности, мы хотим сохранить тот же заголовочный файл и имена переменных.
Как мы можем устранить эту ошибку?
Тандем Детали:
Каждый модуль компиляции — грубо говоря, один исходный файл и все файлы прямо или косвенно #include
г в него — составляется отдельно. Поэтому, если вы включите ваш конкретный заголовок в два отдельных файла, оба из них скомпилируют объявления
gAddress::iterator gAddressIterator; // define iterator
gAddress gAddressMap; // define variable
Потому что они не объявлены extern
они представляют собой определения этих объектов. В результате каждый файл, который включает в себя заголовок, содержит определение каждого из этих объектов, и каждый объектный файл имеет его собственная версия каждого из тех. C ++ допускает множественное декларации одного и того же объекта, но только один определение в каждой полной программе. Потому что каждый из ваших модулей имеет определение gAddressMap
а также gAddressIterator
, вы не можете сформировать соответствующую программу, которая объединяет два.
Решение состоит из двух частей. Во-первых, вы должны убедиться, что объявления файла заголовка не являются определениями. Вы достигаете этого, объявляя их extern
:
extern gAddress::iterator gAddressIterator; // declare iterator
extern gAddress gAddressMap; // declare variable
Во-вторых, вы должны поместить реальные определения куда-то, в один файл из всех, которые вы собираетесь объединить в одну программу. Если есть исходный файл, содержащий функции для инициализации или иного управления этими объектами, то это будет многообещающее место, но не заголовочный файл, который могут включать несколько других файлов.
На мой взгляд, вы должны объявить в заголовочном файле ваши глобальные переменные с extern
квалификатор, потому что эта глобальная переменная используется несколькими C-файлами.
extern gAddress gAddressMap; // define variable