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)
您将包含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)