title: can I declare a global variable in a shared library?
body: <p>Can I declare a global variable inside a library that is later compiled into a shared object ? Is it safe to reference it from other libraries or the main application code by declaring it as extern?  </p>
  
  <p>In theory it works:</p>
  
  <pre><code>[niko@dev1 snippets]$ cat libcode.c 
  int variable;   // &lt;-- this is a global variable declared in a Library
  
  void set_var(int value) {
      variable=value;
  }
  int get_var(void) {
      return variable;
  }
  [niko@dev1 snippets]$ gcc -g -fPIC -c libcode.c 
  [niko@dev1 snippets]$ gcc -o libcode.so -shared libcode.o
  [niko@dev1 snippets]$ cat appcode.c 
  #include &lt;stdio.h&gt;
  // simplified .h declarations:
  extern int variable;
  void set_var(int value);
  int get_var(void);
  
  void main(void) {
  
      set_var(44);
      printf("var=%d\n",variable);
      variable=33;
      int var_copy=get_var();
      printf("var_copy=%d\n",var_copy);
  }
  [niko@dev1 snippets]$ gcc -g -o app -L./ -lcode appcode.c 
  [niko@dev1 snippets]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
  [niko@dev1 snippets]$ ./app
  var=44
  var_copy=33
  [niko@dev1 snippets]$ 
  </code></pre>
  
  <p>Lets review it with the debugger:</p>
  
  <pre><code>[niko@dev1 snippets]$ gdb ./app
  .....
  (gdb) break main
  Breakpoint 1 at 0x40077e: file appcode.c, line 9.
  (gdb) run
  Starting program: /home/deptrack/depserv/snippets/app 
  Missing separate debuginfos, use: dnf debuginfo-install glibc-2.22-16.fc23.x86_64
  
  Breakpoint 1, main () at appcode.c:9
  9       set_var(44);
  (gdb) print &amp;variable
  $1 = (int *) 0x601044 &lt;variable&gt;
  (gdb) s
  set_var (value=44) at libcode.c:4
  4       variable=value;
  (gdb) s
  5   }
  (gdb) s
  main () at appcode.c:10
  10      printf("var=%d\n",variable);
  (gdb) s
  var=44
  11      variable=33;
  (gdb) s
  12      int var_copy=get_var();
  (gdb) s
  get_var () at libcode.c:7
  7       return variable;
  (gdb) s
  8   }
  (gdb) s
  main () at appcode.c:13
  13      printf("var_copy=%d\n",var_copy);
  (gdb) s
  var_copy=33
  14  }
  (gdb) s
  0x00007ffff7839580 in __libc_start_main () from /lib64/libc.so.6
  (gdb) s
  Single stepping until exit from function __libc_start_main,
  which has no line number information.
  [Inferior 1 (process 28380) exited with code 014]
  (gdb) 
  </code></pre>
  
  <p>I say "in theory" it works because when using this approach in a large project I ran into a bug where the referencing such variable gave me unexpected results. The address of the variable was unusually high (0x7ffff767c640) and the only fix was to do declare all global variables inside main application code and use 'extern' to reference them in the code of the library. However, this way, the library could not have variables on its own. See this question for details: <a href="https://stackoverflow.com/questions/39360722/getting-incorrect-address-of-a-variable-during-a-function-call">getting incorrect address of a variable during a function call</a>  </p>