compile warnings on win32 (wincon + vt [which has -Werror so build fails])
GitMensch opened this issue · 2 comments
To debug an issue I've built PDCursesMod on MSYS2 to find wincon and vt ports run some warnings, the later has -Werror
and therefore don't build at all (I know it is deprecated, but wanted to at least verify the build):
../wincon/pdcscrn.c: In function 'PDC_scr_open':
../wincon/pdcscrn.c:484:9: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'BOOL (*)(void *, struct _CONSOLE_SCREEN_BUFFER_INFOEX *)' {aka 'int (*)(void *, struct _CONSOLE_SCREEN_BUFFER_INFOEX *)'} [-Wcast-function-type]
484 | (GetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
| ^
../wincon/pdcscrn.c:487:9: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'BOOL (*)(void *, struct _CONSOLE_SCREEN_BUFFER_INFOEX *)' {aka 'int (*)(void *, struct _CONSOLE_SCREEN_BUFFER_INFOEX *)'} [-Wcast-function-type]
487 | (SetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
| ^
../vt/pdckbd.c: In function 'PDC_get_key':
../vt/pdckbd.c:542:20: error: 'c' may be used uninitialized [-Werror=maybe-uninitialized]
542 | assert( (c[0] & 0xc0) == 0x80);
| ^
../vt/pdckbd.c:377:11: note: 'c' declared here
377 | int c[MAX_COUNT], modifiers = 0;
| ^
../vt/pdckbd.c:549:23: error: 'c' may be used uninitialized [-Werror=maybe-uninitialized]
549 | assert( (c[1] & 0xc0) == 0x80);
| ^
../vt/pdckbd.c:377:11: note: 'c' declared here
377 | int c[MAX_COUNT], modifiers = 0;
| ^
../vt/pdckbd.c:556:26: error: 'c' may be used uninitialized [-Werror=maybe-uninitialized]
556 | assert( (c[2] & 0xc0) == 0x80);
| ^
../vt/pdckbd.c:377:11: note: 'c' declared here
377 | int c[MAX_COUNT], modifiers = 0;
| ^
cc1.exe: all warnings being treated as errors
The WinCon issue is one I've known about and haven't been able to fix. It appears to be an oddball casting issue; the code itself is fine, I just haven't found the right way to make the warning go away. If I could figure it out, I'd change the WinCon flags to include -Werror
, same as most other platforms.
I know it is deprecated, but wanted to at least verify the build
An excellent idea. You can turn up some interesting things that way. This is a case in point.
My hat is off to the folks at Microsoft for detecting this. The problem is that if we get a character with the high bit set, we assume we're going to get a multi-byte sequence, and the code reads the first (usually only) continuation byte. But the code assumes there will be such a byte; the compiler is pointing out that if we don't, c[0]
will be uninitialized.
The reason I'm impressed is that the compiler had to look at check_key()
and realize that it returns TRUE
and sets the character if one is available, and returns FALSE
and doesn't initialize it if there's no input waiting. It was bright enough to see that for the first character we get, we're checking the return value from check_key()
and only using the actual character if it returned TRUE
, and that we didn't make that check further down.
In practice, the multi-byte sequence appears to be provided as a 'unit'. If you get the first byte, you'll get the continuation bytes with no delay. But I could imagine eventually finding a platform where that's not true. If so, we'll be glad we have the assert(0)
s in there.
I've posted the fix (commit 8cf769f). I don't have that version of MSVC, but it seems to be that the code ought to compile without complaint now. (If you find that it works now, please close this issue.)
Should note that I recently tried compiling much of the code with Borland, and found two unused variables (see commit 865b515) and a failure to fully prototype functions (see commit 6af91c0), all of which had slid right past clang, gcc, and MSVC. Not bad for an obsolete compiler!
vt builds now. Note: MSYS2 builds with GCC and CLANG.
This one was presented by
$ gcc --version
gcc.exe (Rev1, Built by MSYS2 project) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
and no more errors with
$ /clang64/bin/cc --version
clang version 14.0.6
Target: x86_64-w64-windows-gnu
either (which does not raise a warning on wincon, likely because a whitelisting of the FARPROC *
).
note: only tested UTF8 WIDE CHTYPE64
Concerning wincon: Is there a reason to directly call the GetModuleHandleA
function instead of GetModuleHandle
or LoadLibraryEx
?
To fix the issue: I think casting it to (void *)
or (void(*)())
first, then to (GetConsoleScreenBufferInfoExFn)
should fix the issue and looks less ugly to me than compiler pragmas.