C中的重复符号错误

Posted

技术标签:

【中文标题】C中的重复符号错误【英文标题】:duplicate symbol error in C 【发布时间】:2014-06-10 14:59:18 【问题描述】:

我有以下代码布局

header.h

#ifndef _header_h
#define _header_h
void empty(float *array, int l)

    int i;
    for (i=1 ; i<=l ; i++)
    
        array[i]=0;
    



#endif

还有两个文件(我们称它们为 file1.c 和 file2.c)

#include "header.h"

void function/*1 or 2*/()

     ....
     empty(a,b);
     ....

所以编译工作正常,但链接器命令失败,因为编译器说存在重复的函数定义。如何在仍然使用头文件的情况下避免这种情况?当我只在头文件中定义函数并创建另一个包含完整函数的 .c 文件时,它工作正常。我一直认为在标题中声明它是要走的路。

【问题讨论】:

不知道为什么人们不赞成你。 【参考方案1】:

我一直认为在标题中声明它是要走的路。

是的,是的。 在标题中声明 没问题。但是,在标题中定义它没有任何好处。 (除非是static inline,但你现在可能不想这样做。)

【讨论】:

【参考方案2】:

在运行的程序中,您永远不应该在头文件中包含需要内存的内容。这是一种粗略的指定方式,但在实践中效果很好。

换句话说,头文件应该只有函数的原型,这是一个编译时的东西,在运行的程序中不“存在”(不像函数的代码本身,当然在运行时存在):

void empty(float *array, int l);

然后将代码放在一个单独的 C 文件中,您可以单独编译和链接。

【讨论】:

“你不应该在标题中定义东西”。除非 things 是枚举或 typedef。 @NikolaiRuhe 不,那些是声明。定义(通常)是在编译程序中占用内存的东西。就像函数的代码或某个变量(“对象”)的位。 C11 标准另有声明。请参阅 6.7 (5) 声明:“定义 [... 枚举常量] 是标识符的(唯一)声明”[和 typedef 名称类似]。 另外,typedef 的名称中甚至还有“定义”。 “你不应该在头文件中包含使编译器将导出的符号发送到目标文件中的东西”怎么样?【参考方案3】:

您将函数empty 定义为标题中的全局符号。这意味着它将在包含它的所有编译单元中成为可见符号。共有三种通用解决方法:

    使其成为静态函数

    static void empty(...) ...
    

    将实现放入单独的编译单元

    header.h:

    void empty(float *array, int l);
    

    empty.c 中实现它

    指示您的链接器忽略重复的符号。这因链接器而异,请咨询man ld

    在 OS X 上:-m 标志。

    在 Linux 上:-z muldefs

【讨论】:

以上是关于C中的重复符号错误的主要内容,如果未能解决你的问题,请参考以下文章

C ++ glfw未解决的外部符号错误[重复]

Xcode中的重复符号错误

Java中的“未定义符号:SQLAllocEnv”错误[重复]

“编译为”设置为“默认”时的外部符号链接错误[重复]

重复符号链接器错误(C++ 帮助)

由于标头中的专业化初始化而避免重复的符号?