bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]