Subject: Re: bug#78160: Emacs fail to build with GCC 15

From: Eli Zaretskii <[email-masked]>
Date: Wed, 30 Apr 2025 13:05:51 +0300

> From: MAN ONE <[email-masked]>
> CC: "[email-masked]" <[email-masked]>
> Date: Wed, 30 Apr 2025 09:23:51 +0000
> msip_labels:
> 
> Thanks, the patch solved the compilation error, and the compiled binary seems working fine.
> However GCC also output some warnings ( actually GCC output a LOT of warnings, I just gonna paste warnings that only relate to the patch.)
> 
> make[2]: Entering directory '/e/home/repo/emacs/lib-src'
>   CC       ntlib.o
>   CCLD     etags.exe
>   CCLD     emacsclient.exe
> emacsclient.c: In function 'w32_give_focus':
> emacsclient.c:1801:17: warning: cast between incompatible function types from 'FARPROC' {a
> ka 'long long int (*)(void)'} to 'BOOL (*)(DWORD)' {aka 'int (*)(long unsigned int)'} [-Wc
> ast-function-type]
>  1801 |   if ((set_fg = (AllowSetForegroundWindow_proc) GetProcAddress (user32, "AllowSetF
> oregroundWindow"))
>       |                 ^
> emacsclient.c:1802:20: warning: cast between incompatible function types from 'FARPROC' {a
> ka 'long long int (*)(void)'} to 'UINT (*)(struct HWND__ *, CHAR *, UINT)' {aka 'unsigned
> int (*)(struct HWND__ *, char *, unsigned int)'} [-Wcast-function-type]
>  1802 |       && (get_wc = (RealGetWindowClassA_proc) GetProcAddress (user32, "RealGetWind
> owClassA")))
>       |                    ^
>   RC       emacsclient.res
>   CCLD     emacsclientw.exe
> emacsclient.c: In function 'w32_give_focus':
> emacsclient.c:1801:17: warning: cast between incompatible function types from 'FARPROC' {a
> ka 'long long int (*)(void)'} to 'BOOL (*)(DWORD)' {aka 'int (*)(long unsigned int)'} [-Wc
> ast-function-type]
>  1801 |   if ((set_fg = (AllowSetForegroundWindow_proc) GetProcAddress (user32, "AllowSetF
> oregroundWindow"))
>       |                 ^
> emacsclient.c:1802:20: warning: cast between incompatible function types from 'FARPROC' {a
> ka 'long long int (*)(void)'} to 'UINT (*)(struct HWND__ *, CHAR *, UINT)' {aka 'unsigned
> int (*)(struct HWND__ *, char *, unsigned int)'} [-Wcast-function-type]
>  1802 |       && (get_wc = (RealGetWindowClassA_proc) GetProcAddress (user32, "RealGetWind
> owClassA")))
>       |                    ^

Please try the below patch instead of the previous one:

diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 2cf90f4..ddfe19f 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -1715,8 +1715,13 @@ set_socket (bool no_exit_if_error)
 }
 
 #ifdef HAVE_NTGUI
-FARPROC set_fg;  /* Pointer to AllowSetForegroundWindow.  */
-FARPROC get_wc;  /* Pointer to RealGetWindowClassA.  */
+typedef void (* VOIDFNPTR) (void);
+typedef BOOL (WINAPI *AllowSetForegroundWindow_proc) (DWORD);
+/* Pointer to AllowSetForegroundWindow.  */
+static AllowSetForegroundWindow_proc set_fg;
+typedef UINT (WINAPI *RealGetWindowClassA_proc) (HWND, LPSTR, UINT);
+/* Pointer to RealGetWindowClassA.  */
+static RealGetWindowClassA_proc get_wc;
 
 void w32_set_user_model_id (void);
 
@@ -1794,8 +1799,8 @@ w32_give_focus (void)
      emacsclient can allow Emacs to grab the focus by calling the function
      AllowSetForegroundWindow.  Unfortunately, older Windows (W95, W98 and
      NT) lack this function, so we have to check its availability.  */
-  if ((set_fg = GetProcAddress (user32, "AllowSetForegroundWindow"))
-      && (get_wc = GetProcAddress (user32, "RealGetWindowClassA")))
+  if ((set_fg = (AllowSetForegroundWindow_proc) (VOIDFNPTR) GetProcAddress (user32, "AllowSetForegroundWindow"))
+      && (get_wc = (RealGetWindowClassA_proc) (VOIDFNPTR) GetProcAddress (user32, "RealGetWindowClassA")))
     EnumWindows (w32_find_emacs_process, (LPARAM) 0);
 }
 #endif /* HAVE_NTGUI */