全局变量的多重定义

时间:2013-01-25 16:33:26

标签: c makefile shared-libraries

  

可能重复:
  constant variables not working in header

在我用来创建共享对象的头文件中,我有以下内容:

#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

任何想法为什么?

4 个答案:

答案 0 :(得分:34)

因为实现文件文件中的每个include都会创建一个新的struct实例(并存储在目标文件中)。

为了避免这种情况,只需在头文件中将结构声明为“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 };

这将解决您的问题。

答案 1 :(得分:6)

在C语言中const对象默认具有外部链接(与C ++相反,默认情况下它们具有内部链接)。因此,在您的代码中,您使用外部链接创建了对象DEFAULT_DSM_CONFIG的多个定义 - 明显违反了C语言的定义规则。

将对象声明为static const(如果您不介意具有内部链接的多个对象)或从头文件中删除定义(仅保留非定义{ {1}} 声明那里。)

无论如何,之前已经多次提出这个问题。请参阅constant variables not working in header或进行搜索。

答案 2 :(得分: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,在链接时间内其他翻译单元不可见。

答案 3 :(得分:2)

每个源文件(.c,而不是.h)都是单独编译的。在每个编译中,dsm_config声明初始值设定项(= { values… }部分)会创建dsm_config的定义。因此,整个程序有多种定义。

通常,头文件只应声明对象而不是定义它们。为此,请删除头文件中的初始化程序,只留下没有初始化程序的声明。在一个源文件中,通过使用初始化程序重复声明来定义dsm_config