From: Gavin Lambert (boost_at_[hidden])
Date: 2021-06-14 23:32:37


On 14/06/2021 5:34 pm, Rainer Deyke wrote:
>> You're assuming that by not specifying an explicit link from B to the
>> standard library that it will inherently have the same settings as P.
>> You're even mostly correct, because the standard library has a bit of
>> special handling in the build tools.
>
> No, I'm saying that by not having a separate compilation step, there is
> literally no way for B to have different settings than P, because there
> is nothing that could be compiled with different settings.  This is true
> regardless of the build system, because it is true at the compile level.
>  There is no set of arguments that the build system can pass to the
> compiler that would cause B to be built with different settings than P.
>
> B is a header-only library.  To use B, the C++ preprocessor literally
> pastes the code from B into P.  Therefore, B /has/ no build settings.
> There are only the build settings from P, which are applied
> indiscriminately to P's own code and the code from B that P #includes.

That's actually completely false. The preprocessor itself *is* build
settings -- defines can be defined differently (along with other
compiler options) between the two builds.

And yes, there may still be two builds. There is the build of P itself
(which includes A) and the build of another library C that is linked
into P but also includes A. Both of these can be via B or separately,
and both can cause different code for B to be generated if the settings
differ, which is an ODR violation.

(Or cause two distinct copies of B to be generated, where C is a shared
library with private visibility, for example.)

For some examples, there's usually a compiler option to choose whether
the standard library is linked as static or as shared, which in turn
causes different #defines to be defined that will affect compilation.
Another example is things that can vary due to the C++ language
selected, or whether or not you've defined various "posix extension"
flags, or library-specific configuration defines. Or something as
simple as compiling one with exception support and one without.

Having a header-only library is not a silver bullet to avoid these kinds
of compilation incompatibilities. In fact it makes some of them worse.