> I highly suggest you not play with this inline stuff. It's something very
fragile that works by
accident; any tiny change could be catastrophic.

Yeah this whole inline thing is a complete mess.  But the headers are
currently broken with Clang, using any of those WS2TCP_INLINE functions
with clang will result in linker errors to unresolved symbols.  See the
original email/patch for more details, but it appears tha Clang is choosing
not to inline some of the calls which makes it incompatible with
__gnu_inline__ which disables the function emission altogether.  jon_y
suggested on IRC that we add these functions to the library itself which
may not be a bad idea at this point.  It would mean not having to touch
these seemingly brittle header files.


> Do things work out if you use the existing __mingw_ovr attribute define?

It appears to fix the issue yes.  Here's a patch with that solution:



From 8f4c87ad8b19bf904ae0357a09e52477d49abea3 Mon Sep 17 00:00:00 2001
From: Jonathan Marler <johnnymar...@gmail.com>
Date: Tue, 13 Jul 2021 03:37:56 -0600
Subject: [PATCH] Use __mingw_ovr for WS2TCPIP_INLINE

---
 mingw-w64-headers/include/ws2ipdef.h |  4 ++--
 mingw-w64-headers/include/ws2tcpip.h | 36 ++++++++++++++--------------
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/mingw-w64-headers/include/ws2ipdef.h
b/mingw-w64-headers/include/ws2ipdef.h
index d440bbcb8..6b10db388 100644
--- a/mingw-w64-headers/include/ws2ipdef.h
+++ b/mingw-w64-headers/include/ws2ipdef.h
@@ -238,9 +238,9 @@ typedef struct group_source_req {
   SOCKADDR_STORAGE gsr_source;
 } GROUP_SOURCE_REQ, *PGROUP_SOURCE_REQ;

-#define WS2TCPIP_INLINE __CRT_INLINE
+#define WS2TCPIP_INLINE __mingw_ovr

-int IN6_ADDR_EQUAL(const struct in6_addr *,const struct in6_addr *);
+static int IN6_ADDR_EQUAL(const struct in6_addr *,const struct in6_addr *);
 WS2TCPIP_INLINE int IN6_ADDR_EQUAL(const struct in6_addr *a, const struct
in6_addr *b) {
     return !memcmp(a, b, sizeof(struct in6_addr));
 }
diff --git a/mingw-w64-headers/include/ws2tcpip.h
b/mingw-w64-headers/include/ws2tcpip.h
index 0a7890bb3..cf7d28ba6 100644
--- a/mingw-w64-headers/include/ws2tcpip.h
+++ b/mingw-w64-headers/include/ws2tcpip.h
@@ -46,24 +46,24 @@ extern "C" {
   extern const struct in6_addr in6addr_any;
   extern const struct in6_addr in6addr_loopback;

-int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *);
-int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *);
-int IN6_IS_ADDR_MULTICAST(const struct in6_addr *);
-int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *);
-int IN6_IS_ADDR_SITELOCAL(const struct in6_addr *);
-int IN6_IS_ADDR_V4MAPPED(const struct in6_addr *);
-int IN6_IS_ADDR_V4COMPAT(const struct in6_addr *);
-int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *);
-int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *);
-int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *);
-int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr *);
-int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr *);
-int IN6ADDR_ISANY(const struct sockaddr_in6 *);
-int IN6ADDR_ISLOOPBACK(const struct sockaddr_in6 *);
-void IN6_SET_ADDR_UNSPECIFIED(struct in6_addr *);
-void IN6_SET_ADDR_LOOPBACK(struct in6_addr *);
-void IN6ADDR_SETANY(struct sockaddr_in6 *);
-void IN6ADDR_SETLOOPBACK(struct sockaddr_in6 *);
+static int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *);
+static int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *);
+static int IN6_IS_ADDR_MULTICAST(const struct in6_addr *);
+static int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *);
+static int IN6_IS_ADDR_SITELOCAL(const struct in6_addr *);
+static int IN6_IS_ADDR_V4MAPPED(const struct in6_addr *);
+static int IN6_IS_ADDR_V4COMPAT(const struct in6_addr *);
+static int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *);
+static int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *);
+static int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *);
+static int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr *);
+static int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr *);
+static int IN6ADDR_ISANY(const struct sockaddr_in6 *);
+static int IN6ADDR_ISLOOPBACK(const struct sockaddr_in6 *);
+static void IN6_SET_ADDR_UNSPECIFIED(struct in6_addr *);
+static void IN6_SET_ADDR_LOOPBACK(struct in6_addr *);
+static void IN6ADDR_SETANY(struct sockaddr_in6 *);
+static void IN6ADDR_SETLOOPBACK(struct sockaddr_in6 *);

 WS2TCPIP_INLINE int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *a) {
return ((a->s6_words[0]==0) && (a->s6_words[1]==0) && (a->s6_words[2]==0)
&& (a->s6_words[3]==0) && (a->s6_words[4]==0) && (a->s6_words[5]==0) &&
(a->s6_words[6]==0) && (a->s6_words[7]==0)); }
 WS2TCPIP_INLINE int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *a) {
return ((a->s6_words[0]==0) && (a->s6_words[1]==0) && (a->s6_words[2]==0)
&& (a->s6_words[3]==0) && (a->s6_words[4]==0) && (a->s6_words[5]==0) &&
(a->s6_words[6]==0) && (a->s6_words[7]==0x0100)); }
-- 
2.25.4


On Tue, Jul 13, 2021 at 3:31 AM Martin Storsjö <mar...@martin.st> wrote:

> On Tue, 13 Jul 2021, LIU Hao wrote:
>
> > 在 7/13/21 5:02 PM, Jonathan Marler 写道:
> >> Thanks for the convenient info.  However, when I try to use
> >> __attribute__((__weak__)) I get a compiler warning from GCC, i.e.
> >>
> >>      extern __inline__ __attribute__((__weak__))
> >>      void foo(void) {}
> >>
> >>      int main(int argc, char *argv[])
> >>      {
> >>          foo();
> >>      }
> >> $ gcc main.c
> >> main.c:2:10: warning: inline function ‘foo’ declared weak [-Wattributes]
> >>      2 |     void foo(void) {}
> >>        |          ^~~
> >>
> >> I'm having a hard time figuring out why I get this warning.  The info
> you
> >> sent looks consistent with the docs I'm finding, but this warning makes
> it
> >> look like GCC thinks the "weak" attribute is redundant?  Note that I
> still
> >> get this same warning if I remove the "extern", so it seems like GCC
> >> doesn't like inline and the weak attribute...any idea why?
> >>
> >>
> >
> > (Please *Reply to All*.)
> >
> > There must have been reasons why GCC ignores `weak` attribute on inline
> > functions [1]. It might be technical limitation, but I think it makes no
> > sense, because 1) Clang accepts, and 2) decomposing the two attributes
> > actually works as expected [2].
>
> Overall I'd suggest to avoid using `weak` if it's possible; it's kinda
> tricky/messy on COFF targets, and IIRC there's a number of cases with
> GCC/binutils where it doesn't quite work as you'd want to. (On ELF it's
> robust though.)
>
> Do things work out if you use the existing __mingw_ovr attribute define?
> That one iirc expands to something which is always inlined and doesn't
> expect any global definition.
>
> // Martin
>
> _______________________________________________
> Mingw-w64-public mailing list
> Mingw-w64-public@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to