title: Global variables, shared libraries and -fPIC effect
body: <p>I made a piece of code which consists in a dynamic library (<code>lib.c</code>), and a main executable (<code>main.c</code>).
  In both files I define a global variable named: <code>int global</code>.
  Not very smart but it's not the question.</p>
  
  <p>When I compile the dynamic library the <code>-fPIC</code> option seems mandatory:</p>
  
  <pre><code>gcc lib.c -fPIC -shared -o lib.so
  </code></pre>
  
  <p>otherwise I get:</p>
  
  <pre><code>/usr/bin/ld: /tmp/ccpUvIPj.o: relocation R_X86_64_32 against '.rodata' can not be used when making a shared object; recompile with -fPIC
  </code></pre>
  
  <p>When I compile the executable it is not.</p>
  
  <pre><code>gcc main.c -fPIC -ldl
  gcc main.c -ldl
  </code></pre>
  
  <p>Both work, but have different behaviours I can not explain, could you ? :</p>
  
  <p>with -fPIC, global in main.c and global in lib.c are the same variables:</p>
  
  <pre><code>global main: 23 (0x601050)
  global lib: 23 (0x601050)
  </code></pre>
  
  <p>without -fPIC, global in lib.c is not correlated to global in main.c:</p>
  
  <pre><code>global main: 23 (0x601048)
  global lib: 0 (0x7f7742e64028)
  </code></pre>
  
  <p>Here is the source :</p>
  
  <p>lib.c</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  int global;
  
  int f_one() {
  
      printf("global lib: %d (%p)\n", global, &amp;global);
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>main.c</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;dlfcn.h&gt;
  
  void * handle;
  int global;
  
  int main() {
  
      int q = 7;
  
      int (* f_one_p)(int a) = NULL;
  
      global = 23;
  
      handle = dlopen("./lib.so", RTLD_NOW);
  
      if (handle == 0) {
          return EXIT_FAILURE;
      }
  
      f_one_p = dlsym(handle, "f_one");
  
      printf("global main: %d (%p)\n", global, &amp;global);
  
      f_one_p(q);
  
      return EXIT_SUCCESS;
  
  }
  </code></pre>
  
  <p>gcc --version: gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2</p>
  
  <p>uname -a: Linux xxx 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:02:55 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux</p>
  
  <p><strong>edit</strong>: code tested under SUN/sparc and x86/Linux architectures with the same kind of unexpected shared global variables (with -fPIC).</p>