Issue
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
- Removed the duplicate Hello() in B.c
- Re-pointed any calls to Hello() in A.c
Questions
- Is renaming the symbol Hello() the only correct solution?
- Is it bad practice to use –allow-multiple-definition option?
- If possible, should the linker be more sentient about intended code
functionality by restricting a functions visibility i.e., understand that Hello() is a duplicate symbol in B.o and calling it from World() should be confined to B.o instead of looking into A.o?
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!
Solution
-
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 ?
Answered By – John3136
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0