Palmira
Palmira

Reputation: 121

Shared global variable in C++ static library: Linux

This in in C++:

A static library "A" defines a global variable foo.

"B" and "C" are two dynamics libraries both depending on A hence linking (statically) with A.

Then B and C end up loaded in the same process (ex: Application loads B and C).

If we are in a windows environment, we will obtain two different instance of foo, one in B and one in C as clearly explained here:

Shared global variable in C++ static library

What about a Linux environment.

Context: We are currently porting a windows project to linux

Upvotes: 4

Views: 4616

Answers (1)

ysdx
ysdx

Reputation: 9335

Each library will ship include a copy of A. However, at runtime only one will be used by all the components of the process.

// h.h
extern int a;
void b(void);
void c(void);

// a.c
#include "h.h"
int a = 0;

// b.c
#include <stdio.h>
#include "h.h"
void b(void)
{
  printf("%i\n", a++);
}

// c.c
#include <stdio.h>
#include "h.h"
void c(void)
{
  printf("%i\n", a++);
}

//main.c
#include <stdio.h>
#include "h.h"
int main()
{
  b();
  c();
}

#Makefile
main: libxc.so libxb.so
    cc -o main main.c -L. -lxc -lxb
libxb.so:
    cc -fPIC -shared a.c b.c -o libxb.so
libxc.so:
    cc -fPIC -shared a.c c.c -o libxc.so
$make
$ LD_LIBRARY_PATH=. ./main
0
1

Symbol table from libxa.so:

    53: 000000000020098c     4 OBJECT  GLOBAL DEFAULT   24 a

From libxc.so:

    53: 000000000020098c     4 OBJECT  GLOBAL DEFAULT   24 a

The default visibility is STV_DEFAULT which according to LSB:

STV_DEFAULT: The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type. That is, global and weak symbols are visible outside of their defining component (executable file or shared object). Local symbols are hidden, as described below. Global and weak symbols are also preemptable, that is, they may by preempted by definitions of the same name in another component.

man 5 elf:

STV_DEFAULT: Default symbol visibility rules. Globa and weak symbols are available to other modules; references in the local module can be interposed by definitions in other modules.

About the SysV ABI:

When resolving symbolic references, the dynamic linker examines the symbol tables with a breadth-first search. That is, it first looks at the symbol table of the executable program itself, then at the symbol tables of the DT_NEEDED entries (in order), then at the second level DT_NEEDED entries, and so on.

If that's not what's expected, using STV_HIDDEN on the symbol prevents it from behind visible outside of the shared object.

In contrast, on Windows a symbol is always imported from a given DLL and the symbols are not exported to other DLLs by default anyway.

Upvotes: 1

Related Questions