1
votes

I have a.h and a.c that gives the interface and implementation of a function

//a.h
#ifndef A_H
#define A_H
int op();
#endif

//a.c
#include "a.h"
int op(){
    return 1;
}

Similarly, I have b.h and b.c that gives the interface of a function of the same name but with a different implementation

//b.h
#ifndef B_H
#define B_H
int op();
#endif

//b.c
#include "b.h"
int op(){
    return 2;
}

Now, I want to link them with the main program

#include <stdio.h>

int op();

int main(){
printf( "returned = %d\n ", op());
}

For that purpose, I first compile a.c and b.c to a.o and b.o respectively.

gcc -c a.c; gcc -c b.c

Then I am trying to link them together. An usual objective here is to let main.c choose the implementation of 'op' using the implementation that appears first in the linking command. So, ideally:

gcc a.o b.o main.c should give me an executable that returns 1 when executed, and gcc b.o a.o main.c should give me an executable that returns 2 when executed. But I get the error message

ld: 1 duplicate symbol for architecture x86_64

to which I am actually not that surprised. My question is: How can I let the first occurred implementation be used by main.c? Thanks.

2
Use manual dynamic linking with dlopen; other than that I see no way to do this without involving some seriously dark hacks.datenwolf
While not random letting the linker pick one implementation looks like a very bad idea in general. What do you actually want to accomplish with that?too honest for this site
gcc a.o main.c or gcc b.o main.c..you are trying oops fundamentals in C..right? It is C not Python or Java..Linker is doing its job well, I hope you understand that.Gaurav Minocha
Put the object codes in separate libraries, then specify the order of the libraries. For example, a.o is in library libA.a and b.o is in library libB.a. Then link using either -lA -lB or -lB -lAFredK

2 Answers

3
votes

One option:

  1. Make two static libraries -- one from a.o and one from b.o.

    ar libA.a a.o
    ar libB.a b.o
    
  2. In the link line, use the library that you want to be given higher priority before the other one.

    gcc main.c -L. -lA -lB
    
3
votes

Depending on linker argument order to select which function to use is in general a bad idea. However, your requirements can be implemented using weak symbols.

To make a function "weak", i.e. overridable by another implementation, mark it with GCC __attribute__((weak)), for example:

int op(void) __attribute__((weak));
int op(void){
    return 2;
}

If you declare both implementations as "weak" in this way, the one that comes first is going to be preferred.

If you mark just one as weak, the other one will be strictly preferred regardless of the linking order. I would suggest to go this way to increase the maintainability of the code.