Gcc Style Weak Linking in Visual Studio

GCC style weak linking in Visual Studio?

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

Is it possible to determine (at runtime) if a function has been implemented?

On GNU gcc / Mingw32 / Cygwin you can use Weak symbol:

#include <stdio.h>

extern void __attribute__((weak)) callMeIfYouDare();

void (*callMePtr)() = &callMeIfYouDare;

int main() {
if (callMePtr) {
printf("Calling...\n");
callMePtr();
} else {
printf("callMeIfYouDare() unresolved\n");
}
}

Compile and run:

$ g++ test_undef.cpp -o test_undef.exe

$ ./test_undef.exe
callMeIfYouDare() unresolved

If you link it with library that defines callMeIfYouDare though it will call it. Note that going via the pointer is necessary in Mingw32/Cygwin at least. Placing a direct call callMeIfYouDare() will result in a truncated relocation by default which unless you want to play with linker scripts is unavoidable.

Using Visual Studio, you might be able to get __declspec(selectany) to do the same trick: GCC style weak linking in Visual Studio?

Update #1: For XCode you can use __attribute__((weak_import)) instead according to: Frameworks and Weak Linking

Update #2: For XCode based on "Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)" I managed to resolve the issue by compiling with the following command:

g++ test_undef.cpp -undefined dynamic_lookup -o test_undef

and leaving __attribute__((weak)) as it is for the other platforms.

static linking in gcc (mingw)

When the linker scans the library files, it only links the object code necessary to resolve the symbols not resolved by earlier object code or libraries. Unreferenced object code from archives will not be linked.

Specifying redundant libraries may extend the build time. You can help that by specifying the most used libraries first, but in all but the largest projects that is unlikely to be significant.

template specialization, different behavior on windows vs gcc?

The first thing is that your code is in violation of the ODR rule if any translation unit includes the header and causes the definition of the specialization without the compiler seeing a declaration. Since that is undefined behavior the fact that one compiler accepts it and the other rejects it is well within reason.

The correct code, as you already figured out is to provide the declaration of the specialization, and that will work in any compiler.

As of why it seems to work or even why does it actually work in gcc, this is most probably a matter of how the code is generated and the linker processes the object files. In particular in gcc the compiler will generate the specialization in the translation unit that needs it (and does not see your own specialization), but it will be marked as a weak symbol. The gcc linker will accept a symbol being multiply defined if all but [at most] one definitions are weak, leaving the strong symbol in the final executable.

Working code tested on Linux throws 'error C3646' on win 7, Visual Studio 12

__attribute__ Is GCC specific. It's a non standard extension.

That's why MSVC is complaining.

Here is a good answer on how to find a workaround to have the equivalent working on Visual Studio for.

In fact, it depends of your usage of the __attribute__ extension. But it is difficult to find an equivalent in MSVC.



Related Topics



Leave a reply



Submit