On Thu, 14 Dec 2000, Mark Kim wrote:

> For one of my classes, we've been using a linker hack to link two
> libraries with the same function names.  It did this by doing something
> like this:
> 
>    library1.h - has function()
>    library1.a - implements function() from library1.h
> 
>    library2.h - has function()
>    library2.a - implements function() from library2.h
> 
>    file1.cc - includes library1.h, uses its function()
>    file2.cc - includes library2.h, uses its function()
>    main.cc - Executes functions in file1 and file2.
> 
> Then:
> 
>    g++ main.o file1.o file2.o -lrary2 -lrary1
> 
> and somehow everything compiles.  Whether it works correctly (calls the
> expected function() calls) or not is another matter, and that's what I'm
> trying to find out -- is there a defined behavior when you do
> this?

The linker starts by "seeding" the destination executable with the object
files you specify, and the making a single pass through the library files,
in the specified order.  If the initial set of object files have
conflicting symbol definitions, you will get errors, because their
inclusion is not optional.  If the linker reaches the end of the object
files and libraries while symbols remain undefined, then you will get
errors.

Libraries contain compilation units that may be linked if the application
references them. For example, if you use printf, then a compilation unit
with a symbol "printf" is added to the executable.  Since printf depends
on other, lower-level functions, the list of symbols to look for as the
linker works its way through the libraries may grow, but once the symbol
is defined it stays defined, and if another instance of the symbol is
found in a library it is ignored.

BTW: Note that libraries almost always contain "compilation units" (the
result of compiling a source file).  If you look in the source for a
library, usually the source files are very small, often with only one or
two functions or variables, so that there may be many more source files
than header files.  This avoids having functions or data that you don't
use linked into your executable.  It is conceivable for a linker to avoid
this, but only with collusion between the linker and the compiler.  The
only compiler/linkers I have heard that do it are certain Ada compilers.
In any event, the symbol resolution would not be affected... this is just
an aside.

>  Anyone know how this linker hack works?

It doesn't.  Ncurses has most (all?) of its functions defined with more
than one name specifically to be able to get around this problem.

In your example, only the function() defined in library2.a would be in the
executable.

>  Does it make use of function overloading in C++?

Are the function signatures (arguments) different? then the linker
business is pointless.  If not, then the second definition is never linked
in.

> (Of course, I'm assuming this is a "hack."  It's a technique I've
> certainly never used or heard of.)

Nor have I.  However, there is a similar coding approach used in C++
multiple inheritance, where the scoping rules ended up quite complicated
so such conflicts could be resolved, and the method signatures make it
possible.  Linkers are much simpler than that (fortunately!).

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<[EMAIL PROTECTED]>        Basics: ##.#.       ##.#.  Live Go...
Work:<[EMAIL PROTECTED]>              Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------

Reply via email to