Recently started C coding on Linux and ran into a 'multiple definition' error (sources A.c and B.c below)
gcc -Wall A.o B.o -o C
/usr/bin/ld: B.o: in function "Hello":
B.c:(.text+0x0): multiple definition of `Hello'; A.o:A.c:(.text+0x0): first defined here
Searching thru S.O, it was suggested to use this linker command line option
--allow-multiple-definition (-z muldefs)
Normally when a symbol is defined multiple times, the linker will report a fatal error.
These options allow multiple definitions and the first definition will be used.
Running this command bypassed the error message
gcc -Wall -Wl,--allow-multiple-definition A.o B.o -o C
It seemed peace was restored, however, it output
./C
Hello A
Hello A
World B
I was expecting this output below and "assumed" the linker would smoothly resolve any symbol conflicts, but at least keep the existing code functionality
Hello A
Hello B
World B
However, the resulting C ELF binary was modified as follows by examining the assembly output from objdump -S -M intel C
Questions
gcc -Wall -c A.c
#include <stdio.h>
void Hello(void)
{
printf("Hello A\n");
}
int main()
{
Hello();
World();
return 0;
}
gcc -Wall -c B.c
#include <stdio.h>
void Hello(void)
{
printf("Hello B\n");
}
void World(void)
{
Hello();
printf("World B\n");
}
EDITED
Based upon the comments/answers, adding the static keyword worked nicely
static void Hello(void)
{
printf("Hello B\n");
}
No need to use that command line option now
gcc -Wall A.o B.o -o C
Hello A
Hello B
World B
The real impetus for the question is that we build a UASM assembly object file, and given the tip about the C static keyword, at least I can now research what's available in UASM to make these functions PRIVATE to the object.
UPDATE
For UASM, was able to make the function scope limited to the object file by adding
PROC PRIVATE FRAME
Thanks!
Name change is best but you could also make them static (to limit access to the file they are in) or change the signature just a little bit.
Yes. Unbelievably bad ! In the real world you're expecting Hello() to do something, but now you're letting the compiler decide which version of Hello() to use - might be right. Might be wrong. It's madness to even have this option (IMHO).
You can do that by making them static.
This is all a bit academic. Why do you think having 2 global scope functions called Hello() is a good idea in the first place ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With