[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: C++ aliases in <netdb.h>
From: |
Pedro Alves |
Subject: |
Re: C++ aliases in <netdb.h> |
Date: |
Fri, 16 Dec 2016 18:24:35 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
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