Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>gcc, in C mode:</strong></p> <p>Uninitialised globals which are not declared <code>extern</code> are treated as "common" symbols, not weak symbols.</p> <p>Common symbols are merged at link time so that they all refer to the same storage; if more than one object attempts to initialise such a symbol, you will get a link-time error. (If they aren't explicitly initialised anywhere, they will be placed in the BSS, i.e. initialised to 0.)</p> <p><strong>gcc, in C++ mode:</strong></p> <p>Not the same - it doesn't do the common symbols thing. "Uninitialised" globals which are not declared <code>extern</code> are implicitly initialised to a default value (0 for simple types, or default constructor).</p> <hr> <p>In either case, a weak symbol allows an initialised symbol to be overridden by a non-weak initialised symbol of the same name at link time.</p> <hr> <p>To illustrate (concentrating on the C case here), I'll use 4 variants of a main program, which are all the same except for the way that <code>global</code> is declared:</p> <ol> <li><p><strong>main_init.c</strong>:</p> <pre><code>#include &lt;stdio.h&gt; int global = 999; int main(void) { printf("%d\n", global); return 0; } </code></pre></li> <li><p><strong>main_uninit.c</strong>, which omits the initialisation:</p> <pre><code>#include &lt;stdio.h&gt; int global; int main(void) { printf("%d\n", global); return 0; } </code></pre></li> <li><p><strong>main_uninit_extern.c</strong>, which adds the <code>extern</code> keyword:</p> <pre><code>#include &lt;stdio.h&gt; extern int global; int main(void) { printf("%d\n", global); return 0; } </code></pre></li> <li><p><strong>main_weak_init.c</strong>, which initialises <code>global</code> and declares it to be a weak symbol:</p> <pre><code>#include &lt;stdio.h&gt; int global __attribute__((weak)) = 999; int main(void) { printf("%d\n", global); return 0; } </code></pre></li> </ol> <p>and <strong>another_def.c</strong> which initialises the same global:</p> <pre><code>int global = 1234; </code></pre> <hr> <p>Using <code>main_uninit.c</code> on its own gives 0:</p> <pre><code>$ gcc -o test main_uninit.c &amp;&amp; ./test 0 </code></pre> <p>but when <code>another_def.c</code> is included as well, <code>global</code> is explicitly initialised and we get the expected result:</p> <pre><code>$ gcc -o test main_uninit.c another_def.c &amp;&amp; ./test 1234 </code></pre> <p>(Note that this case fails instead if you're using C++.)</p> <p>If we try with both <code>main_init.c</code> and <code>another.def.c</code> instead, we have 2 initialisations of <code>global</code>, which won't work:</p> <pre><code>$ gcc -o test main_init.c another_def.c &amp;&amp; ./test /tmp/cc5DQeaz.o:(.data+0x0): multiple definition of `global' /tmp/ccgyz6rL.o:(.data+0x0): first defined here collect2: ld returned 1 exit status </code></pre> <hr> <p><code>main_uninit_extern.c</code> on its own won't work at all - the <code>extern</code> keyword causes the symbol to be an ordinary external reference rather than a common symbol, so the linker complains:</p> <pre><code>$ gcc -o test main_uninit_extern.c &amp;&amp; ./test /tmp/ccqdYUIr.o: In function `main': main_uninit_extern.c:(.text+0x12): undefined reference to `global' collect2: ld returned 1 exit status </code></pre> <p>It works fine once the initialisation from <code>another_def.c</code> is included:</p> <pre><code>$ gcc -o test main_uninit_extern.c another_def.c &amp;&amp; ./test 1234 </code></pre> <hr> <p>Using <code>main_init_weak.c</code> on its own gives the value we initialised the weak symbol to (999), as there is nothing to override it:</p> <pre><code>$ gcc -o test main_init_weak.c &amp;&amp; ./test 999 </code></pre> <p>But pulling in the other definition from <code>another_def.c</code> does work in this case, because the strong definition there overrides the weak definition in <code>main_init_weak.c</code>:</p> <pre><code>$ gcc -o test main_init_weak.c another_def.c &amp;&amp; ./test 1234 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload