<div class="gmail_quote">On 15 April 2012 14:55, Manu <span dir="ltr"><<a href="mailto:turkeyman@gmail.com">turkeyman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote"><div class="im">2012/4/15 "Jérôme M. Berger" <span dir="ltr"><<a href="mailto:jeberger@free.fr" target="_blank">jeberger@free.fr</a>></span><br></div><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>Manu wrote:<br>
> I have multiple definitions because I defined a function from the lib in<br>
> one of my own objects, and then they get linked together.<br>
> If I were to not specify libcmtd, every CRT call would be unresolved,<br>
> except atoi in this case which I implemented in one of my objects. The<br>
> point is, if I implement a function from a library, I get the behaviour<br>
> I expect, which is the linker complains about multiply defined symbols.<br>
> Your saying though, that I should be able to implement a library<br>
> function in my own code, and that will somehow be found prior to<br>
> searching the libs, and since the symbol is resolved, the lib search<br>
> will not take place.<br>
> How is the linker supposed to know which instance (my one in a loose .o<br>
> file, or the one in the lib) is actually 'my' one? What if it was<br>
> contained in 2 different libs, rather than one in a lib, and the other<br>
> in a bundle of loose object files?<br>
><br>
> When and how can I expect the behaviour you propose? I don't follow the<br>
> requirements... or the logic the linker could follow. At link time, it<br>
> no longer know's what's mine from what's in any given libs...<br>
> As far as I was aware, I thought it DID just link every single thing<br>
> given together in one huge blob, and then strips the unreferenced stuff<br>
> as a post process.<br>
<br>
</div>        Symbols from "loose" object files will all be included whether they<br>
are used or not (some linkers have special options to strip unused<br>
symbols from the generated executable aftwerwards).<br>
<br>
        Symbols from libraries will only be included if at least one of the<br>
following conditions applies:<br>
<br>
- Some object file that is already included uses the symbol and no<br>
other already included object file defines the symbol. The included<br>
object files may have been specified explicitly or come from a<br>
library and included because it defines some other symbol that is<br>
already used. Here, "already" means "reading the command line from<br>
left to right";<br>
<br>
- The symbol is inside a library object file and that object file<br>
also defines another symbol that is used from one of the already<br>
included object files.<br>
<br>
<br>
        The linker maintains a list of object files and two lists of<br>
symbols: one for symbols whose definition has already been found<br>
(whether these symbols were used or not) and one for symbols that<br>
are used but whose definition is missing. Then it works like this:<br>
- Initialize the lists to empty;<br>
- Take object files and libraries in the order they are specified on<br>
the command line and/or linker script (possibly adding some implicit<br>
runtime libraries and objects at the end);<br>
- For each explicit object file, add the file to the list of objects<br>
and look at the symbols that are defined and used in this object<br>
file. Update the symbol lists accordingly. Complain if a symbol that<br>
is defined in the object file was already in list of defined symbols<br>
(unless at least one of the definitions is marked "weak");<br>
- Libraries are a collection of object files. For each library, look<br>
through the object files in the library for symbols that are in our<br>
"undefined" list. If any are found, add the corresponding object<br>
files as if they came from the command line. Ignore all other object<br>
files in the library;<br>
- Once you have looked at all the object files and libraries, if<br>
there are still symbols in the "undefined" list, complain unless<br>
those symbols are marked "weak";<br>
- Assemble the object files, updating them where needed with<br>
references to the symbols from the "defined" list.</blockquote></div></div></div><br><div>Right, cheers for taking the time to write all that. I feel considerably more educated on the link process :)</div><div class="im">
<div><br></div><div>
- Libraries are a collection of object files. For each library, look<br>through the object files in the library for symbols that are in our<br>"undefined" list. If any are found, add the corresponding object<br>

files as if they came from the command line. Ignore all other object<br>files in the library;
</div><div><br></div></div><div>This is an interesting point. This suggests I can expect unpredictable behaviour under </div><div>If lib A has object file A:O, and it contains symbols x and y...</div><div><br></div><div>
If I now have my own object, and I define x, but also reference y, it will search for unresolved y in libraries, eventually finding the symbol in A:O, which it will then include right?</div>
<div>As it includes A:O from the lib to resolve y, will it not also pull x in the same object, causing a collision with my existing definition of x?</div><div><br></div><div>Basically, if an object in a lib defines multiple symbols, and I use one, but attempt to 'override' the other, is there a way to avoid this collision?</div>

<div>Is this the reason that CRT implementations always seem to strictly have one single .c file per CRT function?</div>
</blockquote></div><br><div>That said, all of that does not match my observation with the VC linker.</div><div>I defined atoi locally, but it complained straight up. If it was selectively pulling objects containing unresolved symbols from the lib, I shouldn't have seen that error I pasted above, since the symbol was already defined within the object that referenced it, it shouldn't have tried to pull atox.obj...</div>
<div><br></div><div>I'm still going to put all of this down as 'very unpredictable' to anyone who isn't a compiler author, and suggest that maybe if we want the formal ability to override some of the basic druntime functions (malloc/file/assert, etc), we should either make an API to register hooks (like the deprecated assert hook), or at least mark the symbols that are safe to replace as weak, and document it.</div>