Fix Clang link errors and address of ws2 inline functions
The following example works with MSVC but will fail using the mingw headers:
#include <ws2tcpip.h>
int main(int argc, char **argv) {
return (int)&IN6_IS_ADDR_UNSPECIFIED;
}
The reason for this is because MinGW is defining this `IN6_IS_ADDR_UNSPECIFIED` function with
`extern inline __attribute__((__gnu_inline__))`. A function defined with these attributes will
NEVER be emitted. This means you cannot take the address of the function
and if the compiler does not inline a call to it, then you'll get a linker error.
In the Windows SDK in ws2ipdef.h, this function uses the `__inline` attribute
https://docs.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-160
> This keyword tells the compiler that inline expansion is preferred. However, the compiler
> can create a separate instance of the function (instantiate) and create standard calling
> linkages instead of inserting the code inline. Two cases where this behavior can happen are:
> * Recursive Functions
> * Functions that are referred to through a pointer elsewhere in the translation unit.
Note that this function is not defined in any .lib or .dll file in the Windows sdk and/or runtime,
so the only way to be able to take the address of it from the example above is if the compiler
is able to emit the function, or if it's defined elsewhere.
The problem here appears to be the inclusion of `__attribute__((__gnu_inline__))` which is what
tells the compiler NEVER to emit the function definition. Removing this attribute allows the compiler
to emit the function which allows its address to be taken, and prevents linker errors if the compiler
decides not to inline a call to it. These linker errors occur often on Clang even when then functions
are only being called (not even taking the addresses of them) which appears to be caused
by a decision from Clang to not inline calls to these functions in some cases.
Note that this applies to multiple functions in the ws2 header files.
To fix this, I've modified these ws2 functions to use __mingw_ovr instead of __CRT_INLINE along
with adding the "static" modifier to the accompanying function declarations. This should
cause each translation unit to have their own instance of these functions without
causing multiple definition errors. This is not the exact behavior of MSVC's `__inline`
attribute, but it a solution that uses mingw's existing inline mechanisms without coming up
with new ones or modifying existing ones could result in exposing the library to odd corner cases
from obscure platforms/toolchains/stdc implementations.
Signed-off-by: LIU Hao <lh_mouse@126.com>
2 files changed