开发者

C++, is linking order standardized?

开发者 https://www.devze.com 2022-12-14 04:39 出处:网络
On my linux box, I have 2 libraries: libfoo1.a and libfoo2.a and they both contain an implementation of

On my linux box, I have 2 libraries:

libfoo1.a and libfoo2.a

and they both contain an implementation of

void foo(int)

and my main program calls foo:

int main() { foo(1); return 0; }

I compiled the program two ways using g++

g++ main.cpp libfoo1.a libfoo2.a -o a1.out
g++ main.cpp libfoo2.a libfoo1.a -o a2.out

When I run the programs, a1 is clearly using the foo() implementation from libfoo1.a, while a2 clearly used libfoo2. That is, g++ linked whichever foo() that it saw first.

My question (finally) is, is this "greedy" linking policy actually specified in the C++ standard? Or would a different compiler / platform behave differently in an implementation-defined way?

PS: To put the question in practical context, I really like the way this g++ example works. In my real application, I have a legacy libfoo2 that implements many (many!) functions, but I want to provide new implementations for a handful of them in libfoo1. On one hand I could write a whole new interface in libfoo1, implement my handful, then delegate to libfoo2 for the remainder. But I would rather void writing all that delegation code, if I can rely linker to do it for me (even for non-g++ compilers like icc).

PPS: To put it in real practical context, libfoo2 is the blas, and libfoo1 is a homebrew OpenMP implementation of a few of its routines. I'm not ready to shell out for MKL. ATLAS does not multithread the functions I want to call. It is very good at multithreading GEMM, but I need some of the quirkier routines from LAPACK to be fast too (zsptrf / zsptrs / zspr). It appears that the my cache-ignorant OpenMP implementation of these routines ca开发者_如何转开发n do better than it's cache-tuned sequential implementation.

Sorry for the length of post.


The standard doesn't say anything about linking order. I would say it's not good practice to rely on whatever order your compiler uses.


Pretty much any linker will behave as you've described.

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it.

From An Introduction to GCC.


According to the standard, you have two definitions of the same function, which violates the One definition rule. The result is undefined behavior.

Probably the "right" way to handle this would be to take the original archive and extract all the object files from it. Then copy your new object files into the directory, and create a new library containing only the versions of the object files that you want. Finally, link with your combined library (and hope nothing in the original library depended on anything undocumented about any functions you replaced).


From what I can tell, the C++ standard does not involve the linker. That is why, for instance, mingw32 and microsoft's C++ compilers can get away with using different name mangling schemes.

0

精彩评论

暂无评论...
验证码 换一张
取 消