Re: wcwidth broken with gcc 16
Thomas Wolff via Cygwin <[email protected]> Sun, 31 May 2026 19:43:11 +0200
| Newsgroups | gmane.os.cygwin |
|---|---|
| Message-ID | <[email protected]> |
Am 31.05.2026 um 18:53 schrieb Thomas Wolff via Cygwin:
>
> Am 31.05.2026 um 16:50 schrieb ASSI via Cygwin:
>> Thomas Wolff via Cygwin writes:
>>> The implementation was extended to wint_t some years ago just to
>>> enable the functionality indicated above, and it used to work until
>>> gcc 15.
>> That was by accident and dependent on undefined behaviour in the
>> compiler for x86_64 ABI, as explained to you already.
>>
>>> For some change in gcc 16, it is now necessary to adapt the prototype
>>> too, or gcc will apply the wrong extension and yield broken results.
>> You don't own the prototype of a standardised public API function and
>> don't get to change it for that very reason.
> cygwin has changed it already by defining wchar_t as 16-bit. My fix
> only reverts this.
>
>> The fix for your bug is easy enough
> It's just not a fix because it narrows the parameter to 16 bits and
> thus breaks current wcwidth functionality.
>
>> and I don't get why you insist making it even more wrong instead.
> Because it's not wrong but the right thing to do as I had explained
> before.
>
>>
>> --8<---------------cut here---------------start------------->8---
>> diff --git a/newlib/libc/string/wcwidth.c b/newlib/libc/string/wcwidth.c
>> index 8348eefe8..65604c061 100644
>> --- a/newlib/libc/string/wcwidth.c
>> +++ b/newlib/libc/string/wcwidth.c
>> @@ -230,7 +230,7 @@ __wcwidth (const wint_t ucs)
>> }
>> int
>> -wcwidth (const wint_t wc)
>> +wcwidth (const wchar_t wc)
>> {
Well, OK, I see what you mean. Changing the parameter width of the
implementation would probably fix the cases from U+8000 to U+FFFF but
the assignment below would not make any difference.
For characters > 0xFFFF, the prototype width extension would actually be
needed independently from gcc versions, and I still claim it's the right
thing to do, in compensation for the cygwin wchar_t limitation.
>> wint_t wi = wc;
>> --8<---------------cut here---------------end--------------->8---
>>
>> Again, the assignment of wc to wi should do the proper zero extension
>> you seek and keeps the public signature intact (and that was what the
>> code did before your change). The stub then calls the implementation
>> __wcwidth (which does take a wint_t argument), there just is no way of
>> feeding it codepoints above 16 bit (and there never was such a
>> possibility for correct code in Cygwin).
>>
>> Now I get that you think that
>>
>> sizeof(wchar_t) == sizeof(wint_t)
>>
>> should hold like on all GNU systems, but that isn't the case since
>> Cygwin is on Windows and so WCHAR_MAX == 0xffffu (I think you know the
>> backstory to that). So you cannot have code points beyond 16 bits as
>> input to wcwidth anyway and everything else is treated correctly (and as
>> before and after the change). Whether there needs to be a separate API
>> for dealing with such codepoints (essentially in UTF-32) is a separate
>> discussion.
>>
>>
>> Regards,
>> Achim.
>
>
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple