全局变量的多重定义

Ste*_*lsh 14 c makefile shared-libraries

可能重复:
常量变量在标头中不起作用

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

#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
Run Code Online (Sandbox Code Playgroud)

当我编译时,我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

jun*_*nix 38

因为实现文件文件中的每个包含都会创建一个新的结构实例(并存储在目标文件中).

要避免这种情况,只需在头文件中将结构声明为"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 };
Run Code Online (Sandbox Code Playgroud)

这将解决您的问题.


Wer*_*nze 6

每个包含头文件的 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 文件中。

另一个不太好的解决方案是将头文件更改为

静态 const struct dsm_config DEFAULT_DSM_CONFIG = { AUTO_UNMAP, NO_ENABLE_COA };

然后,每个 c 文件定义它自己的 dsm_config,该配置在链接期间对其他翻译单元不可见。


AnT*_*AnT 6

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

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

无论如何,这个问题之前已被问过很多次了.查看不在标头中工作的常量变量或进行搜索.