> 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