C中的重复符号

dar*_*sky 9 c function duplicate-symbol

我有两个源文件:

Source FIle 1(assembler.c):

#include "parser.c"
int main() {
    parse_file("test.txt");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

源文件2(parser.c):

void parse_file(char *config_file);
void parse_file(char *src_file) {
    // Function here
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,在编译它时会给我以下错误: duplicate symbol _parse_file in ./parser.o and ./assembler.o for architecture x86_64

为什么它给我一个parse_file的重复符号?我只是在这里调用这个功能......不是吗?

Bla*_*iev 12

首先,包括源文件在C编程中是一种不好的做法.通常,当前翻译单元应包含一个源文件和一些包含的头文件.

在您的情况下,您会有两个parse_file功能副本,每个翻译单元一个副本.当parser.c编译为目标文件时,它有自己的parse_file功能,assembler.c也有自己的功能.

当给定两个目标文件作为输入时,链接器会抱怨(而不是编译器),每个目标文件都包含它自己的定义parse_file.

你应该像这样重组你的项目:

parser.h

void parse_file(char *);
Run Code Online (Sandbox Code Playgroud)

parser.c

void parse_file(char *src_file) {
    // Function here
}
Run Code Online (Sandbox Code Playgroud)

assembler.c

/* note that the header file is included here */
#include "parser.h"

int main (void) {
    parse_file("test.txt");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


fil*_*ipe 8

您将包含parser.c文件,这意味着该文件中的所有代码都将"复制"到assembler.c文件中.这意味着当编译器编译parser.c时,将编译parser.c的全部内容,然后在编译器编译汇编时再次编译它.

这就是标题的用途.
在标题中,您只能放置声明,因此您可以包含它而无需在不同的翻译单元中再次创建相同的符号.

所以你可以创建一个仅包含函数声明的parser.h:

void parse_file(char *config_file);
Run Code Online (Sandbox Code Playgroud)

然后在你的汇编程序中你只包括标题:

#include "parser.h" //include the header, not the implementation
int main() {
    parse_file("test.txt");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)