On Tue, 21 Aug 2018 at 02:59, Gavin Lambert via Boost
On 19/08/2018 08:17, Andrey Semashev wrote:
There is no problem linking static libraries into shared libraries, I do it every day.
This is not entirely true -- while you can do that, and it can work, it comes with a very big caveat that will trap the unwary.
I'm happy you are commenting on this problem again. Let's say you have a library A and another library B, and an executable C.
Compile everything as shared, now C will dynamically load B and A, and everything will Just Work™.
Compile everything as static, now C will statically contain B and A, and everything will Just Work™.
Compile A as static and B as shared. Now things *might* work, or you might have a problem -- it depends on how the libraries are actually used; in particular whether A is used by B or C or both.
If it's used only by one or the other (and in particular is *not* exposed in the public API of B at all), then everything is fine.
If B does a poor job of hiding its use of A (ie. it's included in public header files, even if not part of public API), and if C uses A as well, you now have an ODR problem. And the problem is worse if A's objects are used in the public API of B.
The key thing to realise is that "A as statically linked into B" and "A as statically linked into C" are technically separate copies of the library. And passing objects around between separate copies of the same library is highly perilous -- a lot of the time you can get away with it (provided that the same compiler settings were used in both cases, so you don't get different memory layouts) -- but some things will be "wrong" such as separate copies of static variables and the like, and this can cause misbehaviour.
This is why you're always encouraged to link to the runtime library as shared -- because since it's a dependency of every other library, the only time it's safe to use it statically is if you don't use *any* shared libraries at all. Otherwise you end up with multiple copies of the runtime, and thus multiple separate heaps, and hilarity ensues.
This is I think not what happens in practice, in vcpkg f.e. creation of a static library will by default also imply that that library is statically linked to the run-time. I also do this when building Boost, while you are actually saying that that option/possibility should not even exist as I presume that the combination of a dynamic library statically linked to the run-time crt makes even less sense. Having multiple copies of other libraries is perhaps less dramatic than
that, and you can make it "safe" if you're very careful about segregation, but it's a highly effective source of potential bugs.
You can only find out that you weren't careful when you are finding it out, which might be a case of Seems To Work™, until it doesn't, as it's a full moon degski -- *“If something cannot go on forever, it will stop" - Herbert Stein* *“No, it isn’t truth. Truth isn’t truth" - Rudolph W. L. Giuliani*