GCC style weak linking in Visual Studio?

C++CVisual StudioGccWeak Linking

C++ Problem Overview


GCC has the ability to make a symbol link weakly via __attribute__((weak)). I want to use the a weak symbol in a static library that users can override in their application. A GCC style weak symbol would let me do that, but I don't know if it can be done with visual studio.

Does Visual Studio offer a similar feature?

C++ Solutions


Solution 1 - C++

You can do it, here is an example in C:

/*
 * pWeakValue MUST be an extern const variable, which will be aliased to
 * pDefaultWeakValue if no real user definition is present, thanks to the
 * alternatename directive.
 */

extern const char * pWeakValue;
extern const char * pDefaultWeakValue = NULL;

#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")

Solution 2 - C++

MSVC++ has __declspec(selectany) which covers part of the functionality of weak symbols: it allows you to define multiple identical symbols with external linkage, directing the compiler to choose any one of several available. However, I don't think MSVC++ has anything that would cover the other part of weak symbol functionality: the possibility to provide "replaceable" definitions in a library.

This, BTW, makes one wonder how the support for standard replaceable ::operator new and ::operator delete functions works in MSVC++.

Solution 3 - C++

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).

Solution 4 - C++

The only way i know. Place each symbol in a separate library. User objects with overrides also must be combined to library. Then link all together to an application. User library must be specified as input file, your lib's must be transfered to linker using /DEFAULTLIB: option.

Solution 5 - C++

There isn't an MS-VC equivalent to this attribute. See http://connect.microsoft.com/VisualStudio/feedback/details/505028/add-weak-function-references-for-visual-c-c. I'm going to suggest something horrible: reading the purpose of it here: http://www.kolpackov.net/pipermail/notes/2004-March/000006.html it is essentially to define functions that, if their symbols exist, are used, otherwise, are not, so...

Why not use pre-processor for this purpose, with the huge caveat of "if you need to do this at all"? (I'm not a fan of recommending pre-processor).

Example:

#ifdef USE_MY_FUNCTION
     extern void function();
#endif

then call appropriately in the application logic, surrounded by #ifdef statements. If your static library is linked in, as part of the linking in process, tweak the defines to define USE_MY_FUNCTION.

Not quite a direct equivalent and very ugly but it's the best I can think of.

Solution 6 - C++

From here:

> ... if a needed symbol can be satisfied without consulting a library, > then the OBJ in the library will not be used. This lets you override a > symbol in a library by explicitly placing it an OBJ. You can also > override a symbol in a library to putting it in another library that > gets searched ahead of the one you want to override. But you can’t > override a symbol in an explicit OBJ, because those are part of the > initial conditions.

This behavior results from the algorithm adopted by the linker.

So for short, to override a function,

  • With GCC, you must use the __attribute__((weak)). You cannot rely on the input order of object files into the linker to decide which function implementation is used.

  • With VS toolchain, you can rely on the order of the object/lib files and you must place your implementation of the function before the LIB that implements the original function. And you can put your implementation as an OBJ or LIB.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondeft_codeView Question on Stackoverflow
Solution 1 - C++RingoView Answer on Stackoverflow
Solution 2 - C++AnTView Answer on Stackoverflow
Solution 3 - C++Michael BurrView Answer on Stackoverflow
Solution 4 - C++denisView Answer on Stackoverflow
Solution 5 - C++user257111View Answer on Stackoverflow
Solution 6 - C++smwikipediaView Answer on Stackoverflow