假设我有三个文件:
//m.h
const int RED = 1;
//m.h ends here
//f1.c
#include "m.h"
//f1.c ends here
//f2.c
#include "m.h"
int main() {return 0;}
//f2.c ends here
单独编译每个都可以,但gcc -Wall f1.o f2.o -o prog
将产生:
multiple definition of 'RED'
现在,如果我用以下代码替换const:
//m.h
enum {RED=1} colors;
//m.h ends here
我将能够编译prog
并使用RED
作为常量,并且不会出现任何multiple definition
错误。
为什么enum
的行为与在不同文件中具有相同名称的全局变量或结构时可见的行为不同?
答案 0 :(得分:4)
枚举常量不是对象,它们只有一个值,但在可执行文件中没有分配。因此,在第二个示例中,RED
只是每个文件中值的定义。另一方面color
不是你的想法。它是名为color
的对象的“暂定”。如果你不使用它,它将不会被分配,一切似乎都很好。但它似乎只是这样。
在第一个示例中,每个文件中都有一个名为const
的{{1}}限定对象。由于它是初始化的,因此这是一个定义,并且在每个RED
文件中生成符号。因此链接器的投诉。
答案 1 :(得分:3)
枚举不会在内存中创建值,这意味着链接时没有地址添加到符号表中。
const变量将在编译对象中具有一个地址,并带有符号名称。当您尝试将两个目标文件链接在一起时,它们每个都具有指向不同地址的相同符号名称“RED”,这是导致冲突的原因。