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

Reply via email to