Menu

#2317 incorrect definitions (WINEVENTPROC, SetTimer) in header files

WSL
closed
nobody
Bug
out-of-date
Waiting_User_Response
False
2017-02-01
2016-11-10
No

GCC version: 5.3.0
MinGW Version: 3.22.4

The following have declaration mismatches with MSVC:
WINEVENTPROC - missed CALLBACK
SetTimer - arg2 type mismatch
(of course, I do not know about possible more similar mismatches;
I just noticed these two trying to compile one program)

WINEVENTPROC function pointer:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd373882%28v=vs.85%29.aspx
typedef void (CALLBACK *WINEVENTPROC)(...)
MinGW: in winable.h and winuser.h it is defined w/o CALLBACK
and GCC assumes these declaration to be different, thus refuses to compile
a program using a function with WINEVENTPROC argument if the function
specified in argument is written with the CALLBACK, as MSVC requires.
Note the CALLBACK is defined as __stdcall in windef.h and the compiler
says a function with the __stdcall and a function without it do not match.

SetTimer function:
https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms644906%28v=vs.85%29.aspx
specifies args:
In_opt HWND hWnd,
In UINT_PTR nIDEvent,
In UINT uElapse,
In_opt TIMERPROC lpTimerFunc
(note arg2 is pointer)
MinGW: in winuser.h it is declared as:
WINUSERAPI UINT WINAPI SetTimer(HWND, UINT, UINT, TIMERPROC);
(note arg2 is UINT)

Both these bugs cause compilation errors when using MinGW
to compile program written e.g. for MicroSoft Visual C.

Discussion

  • Keith Marshall

    Keith Marshall - 2016-11-21
    • status: unread --> pending
    • Category: Unknown --> Waiting_User_Response
     
  • Keith Marshall

    Keith Marshall - 2016-11-21

    Thanks for the report. I take your point about WINEVENTPROC, (it really shouldn't be in <winable.h>, which is obsolete, and utterly wrong throughout, not just w.r.t. this declaration), but it should be declared in <winuser.h>, with the CALLBACK attribute.

    I'm less convinced by your reference to SetTimer(). While I can see that the declaration in MinGW.org's <winuser.h> differs from the current MSDN documentation, it is entirely consistent with its original documentation, as it appears in winhlp32.exe on my Win7 VM. Furthermore, UINT_PTR does not represent a pointer, (as your report implies); it represents an unsigned int with sufficient range to store a pointer, such that the stored value may be cast back to a pointer, with no difference from the original pointer value. On Win32, UINT_PTR and UINT refer to identically the same underlying unsigned int data type, and for me, G++ does not complain that a UINT_PTR argument passed to SetTimer() is incompatible. Can you please provide a SSCCE, to illustrate this issue?

     
  • Keith Marshall

    Keith Marshall - 2016-11-28

    I committed [8d57d9] and [d03bac].

    Raymond Chen's blog gives us a compelling reason to update the declaration of SetTimer(), (and also the declaration for KillTimer() and the typedef for TIMERPROC(), BTW). When these were originally implemented, Win32 was the only game in town, and timer IDs were 32-bit integers; the original UNIT declaration suited well enough. With the advent of Win64, timer IDs have become 64-bit integers on the new platform, while remaining 32-bit on Win32, whereas UINT continues to represent 32-bit integers on both. Thus, while UINT is still perfectly adequate for Win32, it is not suitable for the corresponding Win64 declarations; OTOH, UINT_PTR will DTRT for both.

    This really is detail which should be included in the MSDN pages for the affected functions; shame on Microsoft, for surreptitiously slipping in such a change, without explanation.

    I can now understand how the original declaration may have led to run-time problems, when you compile a Win64 application, (which we don't yet support anyway, so the forward-looking change isn't strictly necessary, for us, at this juncture). It still isn't clear, to me, how it can induce compile-time problems; I'd still like to see your SSCCE to demonstrate that.

     

    Related

    Commit: [8d57d9]
    Commit: [d03bac]


    Last edit: Keith Marshall 2016-11-28
  • Keith Marshall

    Keith Marshall - 2016-11-28
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -9,13 +9,13 @@
    
     WINEVENTPROC function pointer:
     https://msdn.microsoft.com/en-us/library/windows/desktop/dd373882%28v=vs.85%29.aspx
    -typedef void (CALLBACK *WINEVENTPROC)(...)
    +`typedef void (CALLBACK *WINEVENTPROC)(...)`
     MinGW: in winable.h and winuser.h it is defined w/o CALLBACK
     and GCC assumes these declaration to be different, thus refuses to compile
     a program using a function with WINEVENTPROC argument if the function
     specified in argument is written with the CALLBACK, as MSVC requires.
    -Note the CALLBACK is defined as __stdcall in windef.h and the compiler
    -says a function with the __stdcall and a function without it do not match.
    +Note the CALLBACK is defined as `__stdcall` in windef.h and the compiler
    +says a function with the `__stdcall` and a function without it do not match.
    
     SetTimer function:
     https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms644906%28v=vs.85%29.aspx
    
     
  • Keith Marshall

    Keith Marshall - 2017-02-01
    • status: pending --> closed
    • Resolution: none --> out-of-date
     
  • Keith Marshall

    Keith Marshall - 2017-02-01

    Closing, due to lack of timely user response.