C – Multiple definition errors during gcc linking in Linux

Multiple definition errors during gcc linking in Linux… here is a solution to the problem.

Multiple definition errors during gcc linking in Linux

Recently started C coding on Linux and encountered 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

With S.O search, this linker command-line option is recommended

–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 bypasses the error message

gcc -Wall -Wl,–allow-multiple-definition A.o B.o -o C

It seems to have returned to calm, however, it outputs

./C

Hello A
Hello A
World B

I’m expecting the output below and “assuming” that the linker will resolve any symbol conflicts smoothly, but at least preserve the existing code functionality

Hello A
Hello B
World B

However, the generated C ELF binary is checked from
objdump -S -M intel C

    Removed duplicate hello() in

  • B.c
  • Repoint to any call to hello() in

  • A.c

Question

  1. Is renaming the symbol Hello() the only correct solution?
  2. Is it bad practice to use the —allow-multiple-definition option?
  3. Should the linker be more sensitive to the expected code if possible
    The functionality is achieved by limiting the visibility of the function, i.e. understanding that Hello() is a repeating symbol in B.o, and calling it from World() should be limited to B.o instead of viewing < strong>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 on the comments/answers, adding static keywords works well

static void Hello(void)
{
    printf("Hello B\n");
}

You don’t need to use that command-line option now

gcc -Wall A.o B.o -o C

Hello A
Hello B
World B

The real insertion force of this problem is that we build a UASM assembly object file and give hints about the C static keyword, at least I can now look into what’s available in UASM to make these functions private to the object.

Update

For UASM, you can limit the scope of the function to the object file by adding

PROC PRIVATE FRAME

Thanks!

Solution

  1. It’s best to change the names, but you can also make them static (to restrict access to the files they’re in) or change the signature slightly.

  2. Yes. Unbelievably bad! In the real world, you expected Hello() to do something, but now you let the compiler decide which version of Hello() to use – probably right. Probably wrong. It’s crazy to even have this option (IMHO).

  3. You can do this by making them static.

It’s a bit academic. Why do you think it’s a good idea to have 2 global scope functions named hello() in the first place?

Related Problems and Solutions