The following escenario is intriguing me.
(A)
source code library.
(B)
a shared library which includes (A)
(C)
a static library which includes (A)
(D)
, a top level program linking with (B)
and (C)
.
Previously I read the following answer and understood that if the linkage is static the variables are truly static and exist only once in the whole program, but if the linkage is dynamic the static variables exist as many times as the library is included. What happens to static variables when libraries are statically linked
In example if I include N times an static library with the following code, the __immediately_lambda_call
is triggered N times but access to the same gMyClass
.
static MyClass& GetSingleton() {
static std::once_flag flag;
static MyClass* gMyClass;
std::call_once(flag, [&]() { gMyClass = new MyClass(); });
return *gMyClass;
}
static const auto __immediately_lambda_call = []() {
auto& gMyClass = GetSingleton();
return true;
}();
But what happens when the same code is included as dynamic library and static library.
Feel free to ignore the next paragraph. I'm more concerned about how memory is shared between static and dynamic library.
The question is because the top level program (D)
randomly throws me a double free memory
error in a more complex code that I summarize as the following code and I don't understand why, but adding __attribute__((visibility( hidden ))
when the dynamic library is compiled seems to fix the issue.
static const int gMyArr[2] = {1,2};
static const int gMyNum = 1;
class API_STATIC_DYNAMIC MyOtherClass
{
public:
MyOtherClass()
: mMatrix(new int[20])
{}
MyOtherClass()
{
delete[] mMatrix;
}
void doSomething()
{
int d = gMyArr[0];
}
static int gMatrix[10];
static int gNumber;
private:
int *mMatrix;
}
Edit LIBRARY:
API.h
#if defined(STATIC_LIB)
#define API_STATIC_DYNAMIC
#else
#define API_STATIC_DYNAMIC __attribute__((visibility("hidden"))) // removed "default"
#endif
MYLIB.h
class MyLibApi
{
public:
void doSomething();
private:
class MyLibImp;
MyLibImp *mPimpl;
}
MYLIB.cpp
class MyLibImp()
{
public:
MyOtherClass myOther;
}
void MyLibApi::doSomething()
{
mPimpl->myOther->doSomething();
}
Edit APP:
int main()
{
MyLibApi api;
api.doSomething();
MyOtherClass other;
other.doSomething();
return 0;
}