Reputation: 328
I am very confused about the following situation:
I have Linux project (which is written in c) that uses a static library A to get an executable. In this static library A there is a c code which calls sem_init from Linux include. There is include to semaphore.h in the .c file, the file compiled using GCC without warnings. I use ld linker.
Everything was fine until I have added unintentionally a new module(which compiled to the static library B) to the project. New code has a function with the same name (sem_init) but a different signature. Code from A does not include .h file from B that defines the new sem_init().
Now, after the addition of library B to the compilation, I saw that instead of sem_init from semaphore.h, the new sem_init was called from library B.
I know that calling functions with the same name is an awful idea, but within a large project, it can happen unintentionally.
The question: why did this happen??? Why linker has chosen the new sem_init??? Why I did not get a multiple definition linkage error?
Upvotes: 0
Views: 830
Reputation: 136237
When the linker is linking static libraries it looks there for undefined symbols only and if it finds a definition, then it links it in and resolves the symbol. sem_init
happens to come from B
which is linked before -lc
(the GNU C standard library which also implements POSIX sem_init
) is linked, and hence the linker picks up sem_init
from B
and then never looks for sem_init
again, this is why you don't get multiple symbol definition error.
B
library probably doesn't intend to implement POSIX sem_init
with a different parameter list. It probably needs to mark its sem_init
as static
so that it is not visible to other translation units. And/or use a completely different name for it.
Upvotes: 2