سؤال

I have two source files:

Source FIle 1 (assembler.c):

#include "parser.c"
int main() {
    parse_file("test.txt");
    return 0;
}

Source File 2 (parser.c):

void parse_file(char *config_file);
void parse_file(char *src_file) {
    // Function here
}

For some reason, when compiling it is giving me the following error: duplicate symbol _parse_file in ./parser.o and ./assembler.o for architecture x86_64

Why is it giving me a duplicate symbol for parse_file? I am just calling the function here... No?

هل كانت مفيدة؟

المحلول

First off, including source files is a bad practice in C programming. Normally, the current translation unit should consist of one source file and a number of included header files.

What happens in your case is that you have two copies of the parse_file function, one in each translation unit. When parser.c is compiled to an object file, it has its own parse_file function, and assembler.c also has its own.

It is the linker that complains (not the compiler) when given two object files as an input, each of which contains its own definition of parse_file.

You should restructure your project like this:

parser.h

void parse_file(char *);

parser.c

void parse_file(char *src_file) {
    // Function here
}

assembler.c

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

int main (void) {
    parse_file("test.txt");
    return 0;
}

نصائح أخرى

You're including the parser.c file, which means all the code that is in that file will be "copied" to assembler.c file. That means that the entire contents of parser.c will be compiled when the compiler is compiling parser.c, and then it'll be compiled again when the compiler is compiling assembler.c

That's what headers are for.
In the header you can put only the declarations, so you can include it without creating the same symbols again in a different translation unit.

so you can just create a parser.h containing just the declaration of the function:

void parse_file(char *config_file);

then in your assembler.c you include just the header:

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

You are including the .c file which contains the definition of the function parse_file. Thus it is defined twice, once in each translation unit, which is not allowed.

As other answers state, including the source means the file will be copied to parser.c and will be defined there as well in the original place (assembler.c). To solve this, either create a header file with your prototype:

parser.h

void parse_file(char *config_file);

And include that file:

assembler.c

#include "parser.h"
int main() {
    parse_file("test.txt");
    return 0;
}

Or remove the include and provide a clue to the function:

int main() {
    void parse_file(char *);
    parse_file("test.txt");
    return 0;
}

Or even simply remove the include at al. Not good practice, as the compiler (without information on a function) will consider its returned value is an integer and may cause other warnings.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top