0

Suppose we have some static library Library that has some function void x() { foo(); } (let's say, declared in library.h and defined in library.cpp)

The definition void foo(); is in some header file functionality.h.

Furthermore, when we're building Library.lib, we define _BUILDING_LIBRARY (with -DBUILDING_LIBRARY or by whatever means).

Then suppose functionality.cpp looks like this:

#ifdef _BUILDING_LIBRARY
void foo() { do_x(); }
#else
void foo() { do_y(); }
#endif

The question is as follows:

How do I get a project that includes Library and calls x(), but also builds the file functionality.cpp (without _BUILDING_LIBRARY) to pick the desired implementation of foo()?

#include <library.h>
#include <functionality.h>

int main()
{
    x();
    foo();
}

Should execute

do_x();
do_y();

However, a minimal working example shows both calls execute do_y


Someone suggested that this question might give me an answer, but that would mean that Library would provide me with foo() as well (which I don't need nor want, I only need x() from Library).

T. J. Evers
  • 391
  • 1
  • 13
  • Far as I can tell, in this program noting at all comes from the library. `x()` is implemented in the header and so is part of the same source file where `main` is. `functionality.cpp` is presumably compiled and linked into that executable also (otherwise the `#ifdef` has no effect). Or you may get a linker error, due to multiple definitions of `foo` (you'd get that error even if those definitions were identical). Formally, this program is ill-formed, no diagnostic required, by way of violating One Definition Rule. – Igor Tandetnik Jan 18 '21 at 17:32
  • @IgorTandetnik Ah, indeed, let's say ```x()``` is implemented in a cpp rather than in a header (I've edited the question) and yes, ```functionality.cpp``` is compiled and linked into both the library and the executable (that was already stated in the question, but could have been more clear). I've tried building this under both VS and GCC, and there's no linker error, but both calls of ```foo()``` in ```main()``` (through ```x()``` and directly) result in calls to ```do_y()``` – T. J. Evers Jan 18 '21 at 20:22
  • @T.J.Evers "*functionality.cpp looks like ...*" Is that *all* there is in `functionality.cpp`? If so, then you could unconditionally `#define _BUILDING_LIBRARY` then `#include "functionality.cpp"` in `library.cpp`. – dxiv Jan 18 '21 at 20:36
  • 1
    Most likely, when given a list of .obj and .lib files, the linker prefers a symbol defined in an .obj over one defined in a .lib. Recall that static libraries are not linked, they are simply a collection of .obj files, any dependencies are resolved when the executable is linked. So it doesn't matter that `x` is in the library - `foo` is looked up the same way whether called from `x` or from `main`. But again, this program is ill-formed - the fact that it behaves a certain way is merely an accidental artifact of a particular implementation. – Igor Tandetnik Jan 18 '21 at 22:29
  • @dxiv Thanks for the suggestion. Unfortunately, it is not. – T. J. Evers Jan 19 '21 at 11:53
  • We have some solution using namespaces (placing foo in a namespace only when _BUILDING_LIBRARY is defined, and changing the definition of ```x()``` to ```void x() { some_namespace::foo(); }```). I'd love to hear if someone has a more elegant suggestion. – T. J. Evers Jan 19 '21 at 11:59
  • @T.J.Evers if the definition are in the header, you can 1. put `static` before their declaration or 2. put them in anonymous namespace. Both create internal linkage. – apple apple Jan 19 '21 at 13:25

0 Answers0