On 04/15/12 07:08, Nick Sabalausky wrote: > "Walter Bright" <newshou...@digitalmars.com> wrote in message > news:jmdhof$1v3v$1...@digitalmars.com... >> On 4/14/2012 4:54 PM, Manu wrote: >>> I just tried it, and I got the error I expected: >>> >>> LIBCMTD.lib(atox.obj) : error LNK2005: _atoi already defined in Unit.obj >>> >>> In C, I would always explicitly declare weak linkage to do this... what's >>> the >>> point of the weak attribute if not for this? >> >> First you need to find out why you have multiple definitions of the same >> symbol being linked together. For example, do not specify libcmtd.lib to >> the linker, then link, then see what your unresolved symbols are. > > This contradicts what you said earlier about symbols in obj files always > overriding ones in lib files. Either obj symbols override lib symbols or > they conflict. Manu demonstrated that they conflict, rather than override. > How is your suggestion for replacing druntime functions supposed to work > when the linker is just going to bitch about them being "already defined"?
Static libraries (*.a) are basically just collections of compiled objects (*.o). So if you have a library "alloc" module/unit which provides Mutex malloc_mutex; void* malloc(int) {...} void free(void*) {...} when the lib gets built this unit is compiled to "m.o"; then the same thing happens to every other source module, and then all the *.o files are merged into the final "library.a". Now, if you declare your own "malloc" symbol, having the same mangled name, in your application, do not implement the "free" function. and link it like this: "... myapp.o mymalloc.o library.a ...", then the linker will pick up the first "malloc" symbol it finds, ie the one in your "mymalloc.o" file. But if "free" isn't also defined there, but was used in myapp.o (or mymalloc itself) then it's still undefined, so the linker keeps looking for that. It will find it in "library.a"s "alloc.o" module and include that. But as "alloc.o" also defines "malloc" and the two symbols point to different things, there's now a conflict. There's nothing subtle or unpredictable about this - you can assume linking works like this: every missing symbol is looked for in every object that comes *after* the one that needs the symbol. The linker can completely forget about every processed library once it has scanned it once, and move over to the next one given on the command line. There are options to change the behavior (eg ld's "-( -l1 -l2 ... -)"), but then the linker has to keep repeating the process as long as some progress is made - which can obviously be a lot slower and/or require more resources than just providing the libs in the correct order. Some linkers may default to the inefficient cyclical search, compilers can generate the *.o files in different ways that make the issue go away (eg by placing the symbols into different sections, so that pulling in one symbol does not automatically also include other locally unreferenced ones) etc. Then there is also C's special "common" treatment for uninitialized data. But in general the simple approach above should work almost everywhere. On 04/15/12 13:55, Manu wrote: > 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? > Is this the reason that CRT implementations always seem to strictly have one > single .c file per CRT function? Yes. You could use per-symbol function- and data- sections, but, unless the symbols are always supposed to work together, having them in different units is usually best. (D's module system makes things a bit more complicated, as the module name is part of the mangled symbol name and there's also moduleinfo data) artur