c++cone-definition-rule

Object files, static libraries and one-definition rule


Let's imagine I have a compilation line like the following:

gcc <flags...> -o a.out obj1.o obj2.o

where both obj1.o and obj2.o defines void f(int). I will get a multiple-definition error (violation of the one-definition-rule).

Ok, now, imagine the following:

gcc <flags...> -o a.out obj1.o -lstatic_lib

where both obj1.o and static_lib.a defines f(int). I know that a static library is a concatenation of .o files, and for every symbol pending to be solved, is found inside any of the .o files of the static library, then the whole .o that resolves that symbol will be linked into the binary, together with any other symbol that very same .o provides.

That behaviour makes me wonder. Imagine that static_lib.a consists of two objects, static_obj1.o and static_obj2.o, where static_obj1.o is who defines f(int). Since obj1.o already defines f(int) as well, the linker is not looking for it within static_lib.a, and so static_obj1.o won't be theoretically included, but, and this is the question:

NOTE: I'm tagging both C and C++ because I guess the behaviour is the same for both in this regard. If it's not, please clarify, I'm very interested in knowing any behavioural difference. Also, if the behaviour is very different between gcc/clang/visual studio/linux/windows, please clarify. If the behaviour is roughly the same, then focus on gcc over linux.


Solution

  • Would the linker, after integrating static_obj1.o because of f2(int), issue a multiple definition warning because of f1(int) being now twice?

    Yes.

    … one-definition rule…

    This is not governed by the one-definition rule in C++ or the corresponding rule in C. In regard to this linking issue, those rules merely indicate that a conforming program will not contain multiple definitions. They do not govern what happens when linking with multiple definitions. For example: