0

To describe is a little tricky, I think. But I do my best...

Given:

A prog (Prog_A)

A lib (Lib_A) with a class Class_A

And a lib (Lib_B) with (also) a class Class_A and has a member Class_A mClass_A

Both classes Class_A have the function

void Class_A::DoSome(){
...
}

For Class_A in Lib_A then

void Class_A::DoSome(){
std::cout << "LIB_A";
}

For Class_A in Lib_B then

void Class_A::DoSome(){
std::cout << "LIB_B";
}

Prog_A includes Lib_A, Lib_A includes Lib_B. Lib_A and Lib_B is "connected" by Callback's. If I now call mClass_A.DoSome() in Lib_B then it's printing

LIB_A

instead of my expectation 'LIB_B'.

Is this behavior correct, or must I be worried?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
Earlybite
  • 137
  • 1
  • 1
  • 11
  • 3
    Learn more about `virtual` member functions & [vtables](http://en.wikipedia.org/wiki/Virtual_method_table) – Basile Starynkevitch Mar 30 '15 at 13:40
  • What namespaces classes Class_A belong to? – Paolo M Mar 30 '15 at 13:40
  • 1
    Does linux really have anything to do with the question? Make the names distinct or use namespaces to make things clearer for usage. – crashmstr Mar 30 '15 at 13:41
  • Which class is `Class_A mClass_A` a member of? – eerorika Mar 30 '15 at 13:43
  • 2
    This has more to do with .ELF executable format than with Linux itself. For this purposes C++ uses so called 'weak symbols'. These can be present "multiple" times in process image. Each library can define symbol of the SAME name, but the first one wins. PS: is it not an answer for your question. A real answer about name mangling and symbol mapping to .ELF format would be very long. – ibre5041 Mar 30 '15 at 13:46
  • 1
    @BasileStarynkevitch This question has nothing to do with virtual member functions & vtables. It's an ambiguous naming problem. – ArnonZ Mar 30 '15 at 13:50
  • How could this even link? – avakar Mar 30 '15 at 13:51
  • @avakar: Dynamically. It wouldn't statically. – Lightness Races in Orbit Mar 30 '15 at 14:05
  • 3
    @ibre5041, there will be no weak symbols in the scenario described above. Weak symbols are used for inline functions and temploids, but not for every symbol in C++. Maybe you're thinking of ELF symbol interpositioning, which is independent of weak symbols. – Jonathan Wakely Mar 30 '15 at 14:13
  • @Jonathan Wakely you're right. I read the question too quickly. The word "includes" made me think that the library includes headers of class - while the real meaning was that library contains symbols. – ibre5041 Mar 30 '15 at 14:29

1 Answers1

4

Your code is wrong. You have defined Class_A twice, and the definitions do not match.

This is not allowed.

[C++11: 3.2/3]: Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.

[C++11: 3.2/5]: There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D` defined in more than one translation unit, then

  • each definition of D shall consist of the same sequence of tokens;
  • [..]

If you were building the entire program straight up, you'd get a multiple definitions error at link-time; however, since you're linking dynamically, this is not possible and your program is simply broken.

Use namespaces to separate the definitions from each other.

I managed to accidentally cause this problem once when using a custom boost::lexical_cast specialisation I'd found on Stack Overflow in a shared library, not realising that the original, "default" specialisation had been instantiated in a separate shared library. The behaviour I got from the main application was quite unpredictable.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Hi, thanks to all! Mainly I was unsure if I made a mistake and I "redirected" unknown, or it is, in this case, a normal behavior. So, all well. Meanwhile I changed one class name, which is "the same" as to use a namepsace. But good to know for the future. Thank you all very much! Greeting Earlybite – Earlybite Mar 30 '15 at 14:20