3

As far as my practical tests go, when linking a static library (.lib) into your executable in Visual-C++, if any executable .obj file defines a duplicate symbol to one in the static library, the symbol in the static library will be silently ignored.

Confirm ( Feb 18 '10 at 17:46 Michael Burr):

MSVC used to behave such that if a symbol is defined in a .obj file and a .lib it would use the one on the .obj file without warning. I recall that it would also handle the situation where the symbol is defined in multiple libs it would use the one in the library named first in the list.

I can't say I've tried this in a while, but I'd be surprised if they changed this behavior (especially that .obj defined symbols override symbols in .lib files).

A brief test with VS 2010 RC indicates that the behavior I described is still there.

('Windows Static Library with Default Functions' seems also a confirmation to me)


Now first of all, I would love to be proven wrong, but at least for a regular C++ function this seems to be the way it is.

Second, is there any way to prevent this? I have a function, that when any binary links to the static library containing this function, I would like to confirm that the version from the static library is actually used, and not some leftover or whatever in the other project. (Do note: Fn in question is test_suite* init_unit_test_suite(int argc, char* argv[]), (*) so I cannot practically change it because it is from a third party lib.)


(*): This is the Boost.Test main function that should be supplied by a custom static lib of ours. If any dev creates a Unit Test project -- which are linked to the static lib automatically through a property sheet -- but erroneously also defines the function, the build should break instead of using the dev supplied function.

Community
  • 1
  • 1
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • Feature, not a bug. Diagnose with a map file or the linker's /VERBOSE option. – Hans Passant Nov 04 '14 at 16:56
  • 1
    @HansPassant - I never said it's a bug. It just ... well not the optimal thing all of the time. I don't want to diagnose it, I want a build error when it happens. – Martin Ba Nov 04 '14 at 19:57

1 Answers1

0

I think the linker behaves differently if you link against independent obj file, not packaged in a static lib. At the very least you should get some warning/error about symbol duplicity.

When I needed something similar a while ago I too couldn't find it in the MS toolchain, but there are two MS devices that come close and might be handy: __declspec(selectany) and the undocumented #pragma /alternatename. Perhaps linking to an obj file and declaring the symbol as selectany would do the trick? If not, perhaps adding a #pragma comment(linker, "/alternatename:_YourSymbol=_DefaultExeSymbol") in the exe-obj file would do it.

Community
  • 1
  • 1
Ofek Shilon
  • 14,734
  • 5
  • 67
  • 101
  • I actually read you blog post prior to posting the Q, but didn't think it helped. Both `selectany` and `alternatename` are used for the opposite of what I would want, namely getting weak linkage when you don't normally get it. Linking directly to the object file may actually work (seeing how the toolchain works normally), but as this is a 3rd party lib, I currently have no idea how to get at this without making it an unmaintainable mess. – Martin Ba Nov 05 '14 at 12:13
  • Not sure I understand. Don't you want to force weak linkage inside your exe? This is exactly what would cause lib-defined symbols to take over in case of duplicity. IIUC you should be able to get this with pragma alternatename. – Ofek Shilon Nov 05 '14 at 13:35
  • Ah OK. That's another twist. What I really like though is *not* having that symbol at all in my executable and enforce that. You see, this is the Boost.Test main function that should be supplied by a custom static lib of ours. If any dev creates a Unit Test project (these are linked to the static lib automatically through a property sheet) but erroneously also defines the function, the build should break instead of using the dev supplied function. – Martin Ba Nov 05 '14 at 13:55
  • Kind of a hack, but you could still use #pragma /alternatename as above and have the _DefaultExeSymbol break the build. – Ofek Shilon Nov 05 '14 at 14:00