简体   繁体   中英

C/C++ linker order for multiple defined symbols

If I have the same symbol defined in an object file and in a library the GNU linker takes the symbol from the object file. Consider this example:

g++ -L"dir/to/lib" -o Executable Test.o foo.o -lMyLib

If I have defined a function foo with the same signature in both foo.cpp and in a source file "MyLib" was compiled from, the GNU linker always prefers the one from the former if I use this order.

Is this behaviour GNU toolchain specific? Do you know from other linkers that behave the same way? Is this anywhere documented (GNU documentation, C++ standard)? I couldn't find anything...

I would like to use this feature to replace/mock certain functions while doing unit testing (aka link seam).

From http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html :

"the linker searches and processes libraries and object files in the order they are specified"

Maybe.

Exactly how the linker processes the files it was given depends on the linker, but in the exact case you've described, I don't think there will be any variation. When you specify an object file, it is included into your final build, and you will get any symbols it defines from it; if two object files define the same symbol, you will normally get an error from the linker (but there are exceptions, due to weak symbols or Fortran-like handling of data definitions). A library is a collection of object files; the standard handling of a library is for the linker to scan it, and incorporate any objects (and only those objects) which define an otherwise undefined external. If the object file in the library only defines the symbol in question, and its definition has already been resolved by an explicitly specified object file, the linker will not incorporate the object file from the library into the program. If the object file in the library also defines other symbols, however, and one of those resolves an otherwise undefined external, the object file from the library will be incorporated into your program, along with all of the symbols it defines. Which could lead to multiple definitions.

By the language standpoint, the "linking order" is unspecified, and cannot be used in reliable way.

By a platform (toolchain) standpoint it has to be somehow specifyed, and -usually- it consider libraries for all symbols not resolved in objects and objects for all symbold not locally resolved. This allow a developer to mask/replace library functions.

Right now, gcc (as msvc) links in the same order of the command line that launches the linker. Whether this behavior can be "trusted" (in the sense it will be maintained in future releases) is not clear. (The GCC documentation is written using present verbs...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM