0

When I have an abstract base class foo, defined in libX.a

class foo {
    virtual void bar() = 0;
};

... and a derived class foo_impl, defined in libY.a

class foo_impl : public foo {
    void bar() { /* do something */ }
};

... and use both libraries to link a program -lX -lY

int main() {
    foo* my_foo = receive_a_foo_from_somewhere();
    my_foo->bar();
}

Then

  • how can I force the linker to actually link the symbol referring to foo_impl::bar()?
  • does objdump -t program list foo_impl::bar() when it is correctly linked?

EDIT: to clarify, I am using linux with gcc or clang

EDIT 2: had missed virtual for bar()

EDIT 4: I apologize for missing clarity. The question should have been "how can I force the linker to actually include foo_impl::bar() in the executable so it can be resolved at runtime?"

idefixs
  • 712
  • 1
  • 4
  • 14
  • how would he know where to link it to? it is a virtual method that requires dynamic lookup. – Elazar May 27 '13 at 20:51
  • When the virtual table for `foo_impl` is created the member function `foo_impl` is tagged as having been used when an object of that type is instantiated. The linker will then automatically include it in your application. – Captain Obvlious May 27 '13 at 21:20
  • EDIT 3: my_foo**->**bar(); – Yam Marcovic May 27 '13 at 21:20
  • Captain Obvlious, so in my case (I do not know which kind of `foo*` I receive), I would have to somewhere instantiate a dummy `foo_impl` to convince the compiler to include its functionality? – idefixs May 28 '13 at 07:36
  • Is it that, `foo_impl` is the only implementation of `foo` and you want to make all calls to `foo::bar()` automatically translated to `foo_impl::bar()`? Then you need a static_cast. But in that case I suggest you make `foo_impl` parent of `foo`. If it's not the case, then force the linker to link the symbol referring to `foo_impl::bar()` will cause error when the `foo` is in fact not `foo_impl`. – Jiaming Lu May 28 '13 at 07:43
  • no `foo_impl` is **one** implementation of `foo` – idefixs May 28 '13 at 07:46
  • Then how could you know that `my_foo` points to a `foo_impl` and can safely call `foo_impl::bar()`? – Jiaming Lu May 28 '13 at 07:48
  • because every `foo` must implement `bar()` – idefixs May 28 '13 at 07:51
  • Every foo must implement `bar()`, but they can implement differently, not necessary to be `foo_impl::bar()` but can also be `another_foo_impl::bar()`. – Jiaming Lu May 28 '13 at 08:00
  • Couldn't this just be a library order issue? Does specifying `-lX -lY -lX` change the link errors at all? – aschepler May 31 '13 at 20:11
  • Also, something actually being linked does potentially construct a `foo_impl`, I hope? – aschepler May 31 '13 at 20:13
  • Not necessarily. When - for example - the `foo*` originates from a file containing an an abstract serialized `foo`, then there must obviously be some de-serialization code for (amongst others) `foo_impl`. But as long as no `foo_impl` is explicitly used, the de-serialization code might not be linked... – idefixs Jun 02 '13 at 15:08
  • `foo::bar()` is declared private! – curiousguy Jul 15 '13 at 11:54

2 Answers2

0

Since the bar method is defined as virtual, there is no need of static linking. The linking will be done dynamically at runtime based on the object type to which the *my_foo refers to. Regardless of whether it's defined in libX.a or libY.a.

Answer to you question how to force the linker to link the symbol referring to foo_impl::bar()?

You can't force the linker to link to particular implementation. The linking will happen based on which object address you got from receive_a_foo_from_somewhere().

Obviously the implementation should be linked to your exe. If it is not available it will definitely fail. But you can't force linker to link particular implementation,

srajeshnkl
  • 883
  • 3
  • 16
  • 49
  • ...which must fail because the compiler (linker actually) never included libY.a symbols – idefixs May 28 '13 at 07:54
  • Answer to you question how to force the linker to link the symbol referring to foo_impl::bar()? You can't force the linker to link to particular implementation. The linking will happen based on which object address you got from receive_a_foo_from_somewhere(). Obviously the implementation should be linked to your exe. If it is not available it will definitely fail. But you can't force linker to link particular implementation, – srajeshnkl May 28 '13 at 08:22
  • sorry, my mistake. see EDIT 4 – idefixs May 28 '13 at 08:29
  • @idefixs: Then your question is more related to options of gcc compiler to include your static library right? I believe there is nothing to do with virtual also. If you get option of gcc to include static libraries then your problem will be resolved? – srajeshnkl May 28 '13 at 08:53
0

It appears there are at least two ways to get the linker to include foo_impl::bar() functionality in the executable:

  1. With gcc, one can use -Wl,--whole-archive to link an entire static library - no matter what.
  2. As Captain Obvlious pointed out, when foo_impl is used in the program, it's virtual functions are tagged as having been used and are thus included in the executable. This could also be an otherwise useless static dummy foo_impl object.
idefixs
  • 712
  • 1
  • 4
  • 14