-1

Hy, I am having the following structure:

lib1.a
         U f1
00000000 T f2
lib2.a
00000000 T f3


main.c:
   #define f1(a, b) f3(a, b)
   int main(){
    f2(a, b);
   }

Note that f2 uses f1.

Is there a way to compile this that will solve the 'undefined reference' without modifying the code or libraries?

The main question is not why I am getting 'undefined reference' for f1 (because it's undefined, obvious), but how I can compile this without having f1 implemented. Something similar to mapping, I want to be called f3 instead of f1 after the compiling is done something similar to redirect (that is why is the define set in main.c).

Thanks

==== Edited == : Ok, so, due to the fact that the problem is too hard to understand, I'll add the sources:

lib2.c -->$gcc -c lib2.c ; ar rcs lib2.a lib2.o

#include <stdio.h>
#include <stdlib.h>

int f3(int c, char *d)
{
    printf("Rly: %d %s \n", c,d);
    return 1;
}

lib2.h

int f3(int c, char *d);

lib.c -->$gcc -c lib.c ; ar rcs lib.a lib.o

#include <stdio.h>
#include <stdlib.h>

int f2(int c, char *d)
{
    printf("%d %s\n", c,d);
    f1(c,d);
    return 1;
}

lib.h

int f2(int c, char *d);

main.c -->$gcc main.c lib.a lib2.a

#include <stdio.h>
#include <stdlib.h>

#include "lib.h"
#include "lib2.h"

#define f1(a, b) f3(a, b)

int main(int argc, char **argv)
{
    f2(argc, argv[0]);
    return
}

This are the files I created to generate a similar scenario. The lib.a and lib2.a cannot be modified. Only the main.c and how I compile them.

dFroze
  • 41
  • 8
  • 1
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – too honest for this site Sep 21 '17 at 15:46
  • That's not a compiler error. – too honest for this site Sep 21 '17 at 15:47
  • @Olaf thanks for the answer. I'll try to remember that post. But the problem here is not why I am having 'undefined reference', but if there is a way to compile it with the lib1 and lib2 as it is and only with changes in main.c if needed. Note that main.c must call f2 and I want f2 to call f3 instead of f1. – dFroze Sep 22 '17 at 07:32
  • "Note that main.c must call f2" - A macro cannot be called. It is not a function. Read [ask] neither your question nor comment makes sense. Before asking undestand what you **need** and understand the problem yourself. Try _rubberducking_. – too honest for this site Sep 22 '17 at 12:15

1 Answers1

0

You can't accomplish this kind of "redirect" with a macro (#define).

To understand why not, remember that macro expansion is just simple textual substitution which is done by the preprocessor (cpp) - a first pass that runs before the file is handed to the compiler (cc1) which actually creates assembly code. In particular, when you define a macro in main.c, it's only seen during the preprocessing of main.c, so any effect it is going to have must occur there. Macros can sometimes be used instead of functions, but they are really completely different animals.

So in your program, if the identifier f1 was used anywhere in main.c, the preprocessor would substitute it with f3. But it isn't, so the macro doesn't have any effect, and cc1 never knows that it even existed, nor does the linker ld. If you could define the macro in lib.c, it would do what you want, but you say you can't do that.

The simplest and most portable way to achieve what you want is to actually define f1 as a global function in main.c (or any other source file, perhaps a new one).

int f1(int c, char *d)
{
    return f3(c, d);
}

It's also possible to achieve by telling the linker that any references to f1 in the object code should be resolved to f3, but it would be non-portable. If your system uses the GNU ld linker, then

gcc -Wl,--defsym=f1=f3 main.c lib.a lib2.a

would do it. But I would suggest that only as a last resort if for some reason the simple approach is completely unsuitable.


Note that this is only going to work if your f1 has exactly the same prototype (arguments, type of arguments, return type) as the call to f1 in lib.c was expecting. At present your lib.c should produce a warning (always pay attention to warnings!!!!!) because you call f1 without a declaration in scope. In reality lib.c should have a declaration like int f1(int, char*); appearing somewhere before the call. (If you leave it out, you get an "implicit declaration" but you can't trust it to always be correct.)

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • Thank you, great explanation :) The '--defsym' seems the best solution for what I was looking for. – dFroze Sep 24 '17 at 18:26