7

Assume the following simple C code:

file1.c

#include <stdio.h>

char* gets(char* i){
  return i;
}

which is redefining the libC native function gets.

This compiles fine with gcc file1.c.

My question is howcome the linker isn't complaining about duplicate symbols as this function is also defined in libC itself?

Alex
  • 71
  • 1

3 Answers3

1

Because you can override functions from standard libraries in C, check this

Nguyen Cong
  • 174
  • 1
  • 13
  • 2
    Overriding standard library functions is undefined behaviour, although it often (but not always) "works as expected". See [section 7.1.3 (Reserved Identifiers)](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) of the C standard, particularly paragraph 2. – rici Mar 20 '19 at 05:50
1

add option -whole-archive in the link phase, as below:

gcc -c -ofile1.o file1.c
gcc -ofile1 -Wl,--whole-archive -lc file1.o -Wl,--no-whole-archive

result:

file1.o: In function `gets':
file1.c:(.text+0x0): multiple definition of `gets'
file1.o: In function `main':
file1.c:(.text+0x18): undefined reference to `gets@@GLIBC_2.2.5'
collect2: error: ld returned 1 exit status
ccxxshow
  • 844
  • 6
  • 5
0

You ran into undefined behavior see N1570 6.9(p5) External definition:

If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.161)

As can be seen. The Standard allows 2 possibilities:

  1. exactly one definition
  2. no more than one definition.

This might depend on the linkage of libc which itself is system dependent. In case you link libc statically the linker will complain. In case of dynamic linking it have no reasong of complaining.

If you take a look at objdump you will find plt section like

898:   e8 b3 fe ff ff          callq  750 <gets@plt>

Anyway the behavior is undefined.

Some Name
  • 8,555
  • 5
  • 27
  • 77