5

Wy redefinition of function already present in dynamic library does not throws any compilation and linking error?

In the below function

#include "calc_mean.h"
#include <stdio.h>

int mean(int t, int v) {
  return 0;
}

int main () {
  int theMean = mean(3,6);
  printf("\n  %d\n",theMean);
}

Inside the shared library Definition of mean function already present as below.

#include <stdio.h>
#include "calc_mean.h"

int mean(int a, int b) {
  return (a+b)/2;
}

The definition of mean function is already present in the shared library libmean.so. But during compilation I don't see any redefinition error and compilation is successful.

And on successful execution the o/p I see is 0 instead of 4 so the function definition of mean inside the shared library is not getting executed but the one inside the main module is getting executed.

Why is this happening so?

alk
  • 69,737
  • 10
  • 105
  • 255

3 Answers3

7

The linker only links in a function from a library if the function had not yet been found during the compilation/linking process.

The reason for the difference in functionality is that there are different types of symbols. A library function is a weak symbol. It is only included if it is not already defined. nm is a tool for listing the symbols in an object or executable. In its man-page you can find a list of the types of symbols.

There is also a wikipedia page on weak symbols.

alk
  • 69,737
  • 10
  • 105
  • 255
  • Why is it that `nm -D /lib/x86_64-linux-gnu/libc.so.6`tells me that `puts` is `W`, `printf` is `T`, but I can redefined both in a program with GCC? This makes it look like being weak (in the ELF sense) is not the question. – Ciro Santilli OurBigBook.com May 27 '15 at 08:36
1

Having two definitions of one externally-visible function (even if the definitions are identical, for non-inline functions) causes undefined behaviour, with no diagnostic required. (Ref: C99 6.9#5 and Annex J.2)

In C, some illegal code requires a compiler diagnostic and some doesn't. Typically the ones that do not require a diagnostic are because:

  • it would be considered too prohibitive to require all compilers to detect and report the error
  • there were existing systems in use that did not diagnose it and the Standard committee did not want to render an existing implementation non-conforming.

In this case, my guess would be that this is a case of the first one; they wanted to leave open the option for compilers/linkers to implement weak symbols as an extension, so they did not specify that the compiler must give a warning here. Or possibly it is actually difficult to detect this in general, I've never tried to write a linker!

It should be considered a quality-of-implementation issue if no diagnostic is given. Perhaps it is possible to pass different flags to your linker so that it does reject this code; if not then you could put a in bug report or a feature request.

M.M
  • 138,810
  • 21
  • 208
  • 365
-2

Did you link correctly the shared library because the compiler should give the error :

multiple definition of 'mean'