C语言头文件加#ifndef防护仍出现DDP_errList多重定义报错如何解决
错误原因
- 头文件的
#ifndef防护仅作用于单个编译单元(单个.c文件),只能避免同一个.c文件重复引入同一个头文件,无法阻止多个不同的.c文件引入头文件时重复生成全局符号。 - 你直接在头文件中定义了全局数组
DDP_errList,main.c和testArray.c都引入了该头文件,两个编译单元会各自生成一份同名全局DDP_errList实例,链接时就会触发多重定义冲突。 - 额外注意:你的代码存在笔误,头文件命名为
testArray.h,但两个.c文件中写的是#include "DDP.h",需要先统一头文件名引用。
解决方案
方案1(规范写法,推荐)
将数组的实体定义放到.c文件中,头文件仅保留extern声明:
- 修改
testArray.h中的数组部分为声明:
#ifndef testArray #define testArray extern int DDP_Errno; // 头文件仅对外声明数组存在,不做定义 extern const char * DDP_errList[]; void DDP_perror(char* msg); int test(); #endif
- 在
testArray.c中添加数组的实体定义:
#include "testArray.h" #include <stdio.h> // 数组定义放到.c文件中,全局仅生成一份实例 const char * DDP_errList[] = { "err1", "err2" }; int DDP_Errno=-1; int test(){ DDP_Errno = 0; return -1; } void DDP_perror(char * data){ if(DDP_Errno>=0 && DDP_Errno<=1){ fprintf(stderr, "%s : %s\n", data, DDP_errList[DDP_Errno]); }else{ fprintf(stderr,"%s : Success\n",data); } }
补充:你的原有
DDP_perror逻辑还有边界错误,数组只有2个元素,下标最大是1,原来写的<=2会触发数组越界。
方案2(快速适配,仅适用于小型常量数组)
直接给头文件中的数组添加static修饰,限制其作用域仅在当前编译单元可见:
// testArray.h中修改数组定义为 static const char * DDP_errList[] = { "err1", "err2" };
注意:该方案会让每个引入头文件的编译单元都生成独立的
DDP_errList副本,存在少量内存冗余,仅适合非常小的常量数组使用。
内容的提问来源于stack exchange,提问作者MrSolarius
相关产品推荐
相关产品推荐

