title: Multiple symbol definitions and static libraries
body: <p>I have come across a slightly unexpected behaviour of the linking process and I would like to ask for clarification.</p>
  
  <p>It seems that linking against an object file and against a static library containing the same set of symbols is not equivalent. The former results in <code>multiple definition</code> error whereas the latter appears to link correctly.</p>
  
  <h3>Minimal example</h3>
  
  <p>File <code>a.c</code> and <code>b.c</code> are the same:</p>
  
  <pre><code>void myfunc() {
  }
  </code></pre>
  
  <p>File <code>c.c</code> is the "main":</p>
  
  <pre><code>void myfunc();
  
  int main()
  {
      myfunc();
      return -1;
  }
  </code></pre>
  
  <p>The compile-link workflow goes as follows:</p>
  
  <pre><code>$ gcc -c a.c b.c c.c
  $ gcc c.o a.o b.o   # Breaks!
  a.o: In function `myfunc':
  a.c:(.text+0x0): multiple definition of `myfunc'
  b.o:b.c:(.text+0x0): first defined here
  collect2: error: ld returned 1 exit status
  $ ar rvs libb.a b.o
  $ gcc c.o a.o -L./ -lb  # Works fine?
  </code></pre>
  
  <p>My question here is: why is the second linking allowed and the first is not if the symbols contained in the object and the static library are the same?</p>
  
  <p>Also, is this behaviour compiler or system specific?</p>
  
  <h3>Extension</h3>
  
  <p>This is potentially a separate question, but maybe useful to put it here. The problem of multiple references re-emerges with a static library if an additional function is defined in <code>b.c</code> file e.g. for b.c containing</p>
  
  <pre><code>void myfunc() {
  }
  void anotherfunc() {
  }
  </code></pre>
  
  <p>And now the linking step breaks with the same error as before:</p>
  
  <pre><code>gcc b.c 
  gcc -L./ c.o -lb  a.o 
  a.o: In function `myfunc':
  a.c:(.text+0x0): multiple definition of `myfunc'
  .//libb.a(b.o):b.c:(.text+0x0): first defined here
  collect2: error: ld returned 1 exit stat
  </code></pre>