On Thursday 22 January 2026 21:40:21 LIU Hao wrote:
> 在 2025-12-31 02:29, Pali Rohár 写道:
> > +}
> > +_Static_assert(__builtin_types_compatible_p(typeof(fallback_IsDBCSLeadByteEx),
> >  typeof(IsDBCSLeadByteEx)), "Functions fallback_IsDBCSLeadByteEx() and 
> > IsDBCSLeadByteEx() are compatible");
> 
> This is ling is so looong.
> 
> And why is there some times `typeof` but sometimes `__typeof`?

Because I wrote it at different times and I have not spotted those
differences. Sometimes I use one form and sometimes another...

Of course, for consistency it should be same in the one source file.

> Only `typeof`
> and `__typeof__` are documented [1]. As a matter of fact, `__typeof__` is
> supported by MSVC as well, so it definitely should be preferred.
> 
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/Typeof.html

Feel free to choose / change it to __typeof__. I mosty did not know what
is the preferred usage there.

Personally I'm trying to use keywords without underscores where it is
possible (for example non-underscored variants is not possible to use in
header files which can be compiled by -std=c89).

> 
> > +
> > +int __cdecl __mingw_isleadbyte_cp(int c, unsigned int cp)
> > +{
> > +  static __typeof(IsDBCSLeadByteEx) *call_IsDBCSLeadByteEx = NULL;
> > +  if (!call_IsDBCSLeadByteEx) {
> > +    HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
> > +    __typeof(IsDBCSLeadByteEx) *kernel32_IsDBCSLeadByteEx = kernel32 ? 
> > (__typeof(IsDBCSLeadByteEx)*)GetProcAddress(kernel32, "IsDBCSLeadByteEx") : 
> > NULL;
> > +    (void)InterlockedExchangePointer((PVOID*)&call_IsDBCSLeadByteEx, 
> > kernel32_IsDBCSLeadByteEx ?: fallback_IsDBCSLeadByteEx);
> > +  }
> 
> These `? :` are over-complicated, and I don't like the GNU extension very 
> much.

Ok, I would not use them in future changes. Personally I thought that
GNU ?: operator makes code more readable and more compact. That is why I
used C ? : operator and GNU ?: operator.

> Casting between function pointers requires an intermediate cast to
> `intptr_t` or `void*`, otherwise compilers will warn about it.

In this case, the cast is not needed because FARPROC (returned by
GetProcAddress) and typeof(IsDBCSLeadByteEx) have same return value and
same calling convention. That is why I have not used it in this time.

Anyway, to be more precise or pedantic, casting between function and
data pointers may cause other warnings as such casting is not defined in
C. Maybe those warning will appear only with -pedantic or similar flags,
I'm not sure now.
The correct way should be casting it via intermediate (void(*)(void))
function pointer which does not generate any warning for neither gcc,
clang and msvc. CRT headers have for it special type _PVFV. So the most
correct way should be something like:

  farproc = (FARPROC)(_PVFV)fallback_IsDBCSLeadByteEx;

> I have simplified this a little [2][3]:
> 
>     FARPROC farproc = NULL;
>     HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
>     if (kernel32)
>       farproc = GetProcAddress(kernel32, "IsDBCSLeadByteEx");
>     if (!farproc)
>       farproc = (FARPROC)(PVOID)fallback_IsDBCSLeadByteEx;
>     (void)InterlockedExchangePointer((PVOID*)&call_IsDBCSLeadByteEx, 
> (PVOID)farproc);
> 
> Despite these issues, the changes are very simple and straight forward. If
> these changes pass the CI, I can push them tomorrow.
> 
> [2] 
> https://github.com/lhmouse/mingw-w64/commit/a22c8e74f2ab108b18758aa2ae2a8334e999eca7
> [3] 
> https://github.com/lhmouse/mingw-w64/commit/cf3a23755035c82e4de4d620caf4f2882857d6d0

Ok, that is fine.


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to