title: Multiple definition errors during gcc linking in Linux
body: <p>Recently started C coding on Linux and ran into a 'multiple definition' error (sources <strong>A.c</strong> and <strong>B.c</strong> below)</p>
  <p><strong>gcc -Wall A.o B.o -o C</strong></p>
  <blockquote>
  <p>/usr/bin/ld: B.o: in function &quot;Hello&quot;:<br> B.c:(.text+0x0): multiple
  definition of `Hello'; A.o:A.c:(.text+0x0): first defined here</p>
  </blockquote>
  <p>Searching thru S.O, it was suggested to use this linker command line option</p>
  <blockquote>
  <p><strong>--allow-multiple-definition</strong> (-z muldefs)<br> Normally when a symbol is defined multiple times, the linker will report a fatal
  error.<br>These options allow multiple definitions and the first
  definition will be used.</p>
  </blockquote>
  <p>Running this command bypassed the error message</p>
  <p><strong>gcc -Wall -Wl,--allow-multiple-definition A.o B.o -o C</strong></p>
  <p>It seemed peace was restored, however, it output</p>
  <p><strong>./C</strong></p>
  <blockquote>
  <p>Hello A<br>Hello A<br>World B</p>
  </blockquote>
  <p>I was expecting this output below and &quot;assumed&quot; the linker would smoothly resolve any symbol conflicts, but at least keep the existing code functionality</p>
  <blockquote>
  <p>Hello A<br>Hello B<br>World B</p>
  </blockquote>
  <p>However, the resulting <strong>C</strong> ELF binary was modified as follows by examining the assembly output from
  <strong>objdump -S -M intel C</strong></p>
  <ul>
  <li>Removed the duplicate Hello() in <strong>B.c</strong></li>
  <li>Re-pointed any calls to Hello() in <strong>A.c</strong></li>
  </ul>
  <p><strong>Questions</strong></p>
  <ol>
  <li>Is renaming the symbol Hello() the only correct solution?</li>
  <li>Is it bad practice to use <em>--allow-multiple-definition</em> option?</li>
  <li>If possible, should the linker be more sentient about intended code
  functionality by restricting a functions visibility i.e., understand that Hello() is a duplicate symbol in <strong>B.o</strong> and calling it from World() should be confined to <strong>B.o</strong> instead of looking into <strong>A.o</strong>?</li>
  </ol>
  <p><br><br></p>
  <p><strong>gcc -Wall -c A.c</strong></p>
  <pre><code>#include &lt;stdio.h&gt;
  
  void Hello(void)
  {
      printf(&quot;Hello A\n&quot;);
  }
  
  int main()
  {
      Hello();
      World();
  
      return 0;
  }
  </code></pre>
  <p><strong>gcc -Wall -c B.c</strong></p>
  <pre><code>#include &lt;stdio.h&gt;
  
  void Hello(void)
  {
      printf(&quot;Hello B\n&quot;);
  }
  
  void World(void)
  {
      Hello();
      printf(&quot;World B\n&quot;);
  }
  </code></pre>
  <p><strong>EDITED</strong></p>
  <p>Based upon the comments/answers, adding the static keyword worked nicely</p>
  <pre><code>static void Hello(void)
  {
      printf(&quot;Hello B\n&quot;);
  }
  </code></pre>
  <p>No need to use that command line option now</p>
  <p><strong>gcc -Wall A.o B.o -o C</strong></p>
  <blockquote>
  <p>Hello A<br>Hello B<br>World B</p>
  </blockquote>
  <p>The real impetus for the question is that we build a UASM assembly object file, and given the tip about the C static keyword, at least I can now research what's available in UASM to make these functions PRIVATE to the object.</p>
  <p><strong>UPDATE</strong></p>
  <p>For UASM, was able to make the function scope limited to the object file by adding</p>
  <pre><code>PROC PRIVATE FRAME
  </code></pre>
  <p>Thanks!</p>