Множественное определение глобальной переменной
Возможный дубликат:
постоянные переменные, не работающие в заголовке
В моем файле заголовка, который я использую для создания общего объекта, у меня есть следующее:
#ifndef LIB_HECA_DEF_H_
#define LIB_HECA_DEF_H_
struct dsm_config {
int auto_unmap;
int enable_copy_on_access;
};
enum { NO_AUTO_UNMAP, AUTO_UNMAP } unmap_flag;
enum { NO_ENABLE_COA, ENABLE_COA } coa_flag;
const struct dsm_config DEFAULT_DSM_CONFIG = { AUTO_UNMAP, NO_ENABLE_COA };
<more code ...>
#endif
При компиляции я получаю следующую ошибку:
cc -g -Wall -pthread libheca.c dsm_init.c -DDEBUG master.c -o master
/tmp/cciBnGer.o:(.rodata+0x0): multiple definition of `DEFAULT_DSM_CONFIG'
/tmp/cckveWVO.o:(.rodata+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [master] Error 1
Любые идеи, почему?
Ответы
Ответ 1
Поскольку при каждом включении в файл файла реализации создается новый экземпляр вашей структуры (и сохраняется в объектном файле).
Чтобы этого избежать, просто объявите структуру как "extern" в файле заголовка и инициализируйте ее в файле реализации:
// In your header file:
extern const struct dsm_config DEFAULT_DSM_CONFIG;
// In your *.c file:
const struct dsm_config DEFAULT_DSM_CONFIG = { AUTO_UNMAP, NO_ENABLE_COA };
Это решит вашу проблему.
Ответ 2
В языке C const
объекты имеют внешнюю связь по умолчанию (в отличие от С++, где по умолчанию они имеют внутреннюю привязку). Таким образом, в вашем коде вы создали несколько определений объекта DEFAULT_DSM_CONFIG
с внешней связью - явное нарушение правил определения языка C.
Объявите свой объект как static const
(если вы не возражаете против наличия нескольких объектов с внутренней связью) или удалите определение из файла заголовка (оставьте там только не определяющее объявление extern const
).
В любом случае, вопрос задавался много раз. См. постоянные переменные, не работающие в заголовке, или выполните поиск.
Ответ 3
Каждый c файл, содержащий ваш файл заголовка, имеет строку
const struct dsm_config DEFAULT_DSM_CONFIG = {AUTO_UNMAP, NO_ENABLE_COA};
Итак, каждый из этих файлов c определяет переменную dsm_config. Если вам нужна только одна переменная dsm_config, вам нужно изменить объявление в файле заголовка на
extern const struct dsm_config DEFAULT_DSM_CONFIG;
и добавьте определение
const struct dsm_config DEFAULT_DSM_CONFIG = {AUTO_UNMAP, NO_ENABLE_COA};
только в одном файле c.
Другим, не очень хорошим решением является изменение файла заголовка на
static const struct dsm_config DEFAULT_DSM_CONFIG = {AUTO_UNMAP, NO_ENABLE_COA};
Затем каждый c файл определяет его собственный dsm_config, который не отображается для других единиц перевода во время ссылки.
Ответ 4
Каждый исходный файл (.c, not.h) скомпилирован отдельно. В каждой из этих компиляций объявление dsm_config
с инициализатором (часть = { values… }
) создает определение dsm_config
. Таким образом, вся программа имеет несколько определений.
Как правило, файлы заголовков должны только объявлять объекты и не определять их. Для этого удалите инициализатор в файле заголовка, оставив только объявление без инициализатора. В одном исходном файле определите dsm_config
, повторив объявление с помощью инициализатора.