While answering this question I decided to check myself and did a little experiment. There are three files:
// moo.h
#ifndef MOO_H
#define MOO_H
#include
struct Moo
{
Moo() {
std::cout << "Moo: " << static_cast(this) << "\n";
}
~Moo() {
std::cout << "~Moo: " << static_cast(this) << "\n";
}
};
void dummy();
#endif
// libmoo.cpp
#include "moo.h"
Moo moo;
void dummy() {}
// main.cpp
#include "moo.h"
Moo moo;
int main()
{
dummy();
}
I then built an executable and a shared library out of these.
g++ -shared -o libmoo.so moo.cpp -fPIC
g++ -o main main.cpp -L. -lmoo -Wl,-rpath=.
As expected, the two moo objects got merged and the ctor/dtor ran for it twice:
Moo: 0x5b923c8ee151
Moo: 0x5b923c8ee151
~Moo: 0x5b923c8ee151
~Moo: 0x5b923c8ee151
Now, according to my own advice in my answer to that question, I rebuilt the shared library with -Bsymbolic, expecting that the two objects now will be separate and the program will print different addresses for them. To my astonishment, the addresses still were the same!
Moo: 0x607411e83151
Moo: 0x607411e83151
~Moo: 0x607411e83151
~Moo: 0x607411e83151
I tried different compiler and linker options, including -fno-weak -fno-inline-functions and -pie, but to no avail. The addresses were always the same.
What is going on here? Is there a way to build the library and/or the executable such that the objects are separate?