On Monday 05 August 2024 17:54:34 Pali Rohár wrote:
> On Monday 05 August 2024 23:04:21 LIU Hao wrote:
> > 在 2024-08-05 20:14, Antonin Décimo 写道:
> > > C99 in Annex J.5.7 Function pointer casts states:
> > > 1 A pointer to an object or to void may be cast to a pointer to a
> > > function, allowing data to be invoked as a function (6.5.4).
> > > 2 A pointer to a function may be cast to a pointer to an object or to
> > > void, allowing a function to be inspected or modified (for example, by
> > > a debugger) (6.5.4)
> > > 
> > > and MSVC, clang, and GCC implement this extension.
> > 
> > GCC warns about it if `-Wpedantic` is specified:
> > (https://gcc.godbolt.org/z/e4bh3jcvs)
> >    ```
> >    <source>:6:12: warning: ISO C forbids conversion of function pointer
> >    to object pointer type [-Wpedantic]
> >        6 |     return (void*) fn;
> >          |            ^
> >    ```
> > 
> > And that's the reason for not doing that. On a system with segmented memory,
> > a pointer to code may assume a different segment from a pointer to data, so
> > even they may appear to hold the same numeric value, they don't point to the
> > same identity.
> 
> Ok, but if the C99 standard even defines (u)intptr_t for object pointers
> only (as Antonin wrote) then compiler can throw warning also for casting
> function pointer to (u)intptr_t type. Or can do it in future version...
> 
> But now I see that casting function pointer to integer and back looks to
> be more safe than casting function pointer to object pointer (and back).

I have looked that (void(*)(void)) gcc generic-function casting which
Antonin pointed out. It is basically normal function pointer for
function which do not take any argument and returns void (no value).

Both msvc and clang supports this kind of function pointer and
surprisingly allows to cast without any warning between any function
pointer to this one and vice-versa, so including casting to FARPROC
function pointer.

Some resources:
https://gcc.gnu.org/gcc-14/porting_to.html#int-conversion
https://stackoverflow.com/a/31482834

So what about this change? It completely avoids casting between function
and data pointers.

diff --git a/mingw-w64-headers/include/wspiapi.h 
b/mingw-w64-headers/include/wspiapi.h
index c95c46abcc54..80be549d4135 100644
--- a/mingw-w64-headers/include/wspiapi.h
+++ b/mingw-w64-headers/include/wspiapi.h
@@ -45,9 +45,9 @@ extern "C" {
     FARPROC pfAddress;
   } WSPIAPI_FUNCTION;
 
-#define WSPIAPI_FUNCTION_ARRAY { { "getaddrinfo",(FARPROC) 
WspiapiLegacyGetAddrInfo }, \
-  { "getnameinfo",(FARPROC) WspiapiLegacyGetNameInfo }, \
-  { "freeaddrinfo",(FARPROC) WspiapiLegacyFreeAddrInfo } }
+#define WSPIAPI_FUNCTION_ARRAY { { "getaddrinfo",(FARPROC)(void(*)(void)) 
WspiapiLegacyGetAddrInfo }, \
+  { "getnameinfo",(FARPROC)(void(*)(void)) WspiapiLegacyGetNameInfo }, \
+  { "freeaddrinfo",(FARPROC)(void(*)(void)) WspiapiLegacyFreeAddrInfo } }
 
   char *WINAPI WspiapiStrdup (const char *pszString);
   WINBOOL WINAPI WspiapiParseV4Address (const char *pszAddress,PDWORD 
pdwAddress);

Could you check if this compiles fine with latest clang version?

It looks like that gcc in following modes is happy:

* -xc -std=c89 -pedantic -Wall -Wextra -Wpedantic -O2
* -xc -std=c17 -pedantic -Wall -Wextra -Wpedantic -O2
* -xc++ -std=c++98 -pedantic -Wall -Wextra -Wpedantic -O2
* -xc++ -std=c++17 -pedantic -Wall -Wextra -Wpedantic -O2

> > Thankfully all Windows targets (maybe all POSIX systems too) have a flat 
> > address space.
> 
> Win9x had flat address space, but it did not started at zero because
> segmentation was active.
> 
> And I heard that some POSIX system (I think it was some BSD?) used
> segmentation just as a memory protection against executing non-code
> memory. That was for 32-bit x86 HW without NX bit support in paging.


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

Reply via email to