On 12/15/2016 12:11 PM, Gisle Vanem wrote: > I get errors from MSVC in <netdb.h> i C++ mode. E.g. in compiling > test-netdb-c++.cc: > > netdb.h(189): error C2440: 'return': cannot convert > from 'INT (__stdcall *)(PCSTR,PCSTR,const ADDRINFOA *,PADDRINFOA *)' to > 'gnulib_::_gl_getaddrinfo_wrapper::type' > > Ditto error for '_gl_freeaddrinfo_wrapper'. > > Some of the pre-processed output of the _GL_CXXALIAS_SYS() macro at > line 189 in netdb.h is: > namespace gnulib_ { > static const struct _gl_getaddrinfo_wrapper { > typedef int (*type) (const char * nodename, > const char * servname, > const struct addrinfo * hints, > struct addrinfo ** res); > __inline operator type () const > { > return ::getaddrinfo; << !! error is here > } > } > getaddrinfo = {}; > } > > Instead this requires a 'reinterpret_cast<type>'. > Hence with this patch, it compiles and runs fine:
Can't see how that can run fine? The compiler will set up the call assuming cdecl convention, while the called function has stdcall convention. > > --- a/netdb.in.h 2016-01-30 20:42:17 > +++ b/netdb.in.h 2016-12-15 12:53:28 > @@ -170,7 +170,7 @@ > struct addrinfo **restrict res) > _GL_ARG_NONNULL ((4))); > # endif > -_GL_CXXALIAS_SYS (getaddrinfo, int, > +_GL_CXXALIAS_SYS_CAST (getaddrinfo, int, > (const char *restrict nodename, > const char *restrict servname, > const struct addrinfo *restrict hints, > @@ -184,7 +184,7 @@ > _GL_FUNCDECL_SYS (freeaddrinfo, void, (struct addrinfo *ai) > _GL_ARG_NONNULL ((1))); > # endif > -_GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai)); > +_GL_CXXALIAS_SYS_CAST (freeaddrinfo, void, (struct addrinfo *ai)); > _GL_CXXALIASWARN (freeaddrinfo); > > # if @REPLACE_GAI_STRERROR@ > > --------- > > This is because of Winsock's __stdcall I assume? I assume so. m4/inet_pton.m4 has this: dnl Most platforms that provide inet_pton define it in libc. dnl Solaris 8..10 provide inet_pton in libnsl instead. dnl Solaris 2.6..7 provide inet_pton in libresolv instead. dnl Native Windows provides it in -lws2_32 instead, with a declaration in dnl <ws2tcpip.h>, and it uses stdcall calling convention, not cdecl dnl (hence we cannot use AC_CHECK_FUNCS, AC_SEARCH_LIBS to find it). HAVE_INET_PTON=1 INET_PTON_LIB= gl_PREREQ_SYS_H_WINSOCK2 if test $HAVE_WINSOCK2_H = 1; then AC_CHECK_DECLS([inet_pton],,, [[#include <ws2tcpip.h>]]) if test $ac_cv_have_decl_inet_pton = yes; then dnl It needs to be overridden, because the stdcall calling convention dnl is not compliant with POSIX. REPLACE_INET_PTON=1 INET_PTON_LIB="-lws2_32" else HAVE_DECL_INET_PTON=0 HAVE_INET_PTON=0 fi else Given the "stdcall calling convention is not compliant with POSIX", I wonder whether the right fix would be to somehow cause those functions to be replaced too? Are all MSVC C run time functions __stdcall, or just a few? It's been a long while since I used MSVC. I suppose a possible fix would be to change from using a conversion operator to a function call operator. Like: inline rettype operator() parameters \ { \ return ::func arguments; \ } \ But, then you'd need to tweak the _GL_CXXALIAS_SYS macro too, to pass down the right "arguments", since that "arguments" doesn't exist today. Like: -_GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai)) +_GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai), (ai)) Thanks, Pedro Alves