Hi Achim,
Am 31.05.2026 um 20:25 schrieb ASSI via Cygwin:
Thomas Wolff via Cygwin writes:
cygwin has changed it already by defining wchar_t as 16-bit. My fix
only reverts this.
Nope. That's not a Cygwin thing and wchar_t can be anything, even less
than 16bit, as far as the standards are concerned. Yes, that's messy,
but it is what it is.
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.
It doesn't break anything that wasn't already broken before. There can
be no correct Cygwin program that can use an argument to wcwidth that
has more than 16 bits (and your own example doesn't use any of these
anyway). The public interface always was wchar_t (nee unsigned short on
Cygwin) and the extension to the win_t in the implementation function in
newlib libc just wasn't working as you (still?) seem to think it does
when you mismatch the types. The type extension of function arguments
(via register sharing) on x86_64 is undefined, the resulting upper 16
bits in this case (wchar_t --> wint_t) can be anything: zero extension,
sign extension or even random bits. This is just not something that can
work reliably. I don't know what aarch64 does on that front.
In your example, you use an int as argument, which is used as a function
argument declared as short unsigned (via wchar_t, so it gets truncated
to 16 bit, at least logically) and then used an int again inside the
actual implementation of that function. This is wrong as the prototype
and the implementation don't match, but the ABI only guarantees that the
lower 16 bit of the original argument transfer in that case. Even if
zero extension was used you'd lose any upper bits in the original
argument anyway (which you say works for your example and I'd argue that
there can't be any upper bits anyway on Cygwin, see aboive), which is
exactly what will _definitely_ happen if the libc implementation stub is
reverted to the correct signature.
You explain what I had already conceded before, that I had overlooked
the prototype and the intended functionality did not work:
printf("%d\n", wcwidth(0x13000)); // should be 1
printf("%d\n", wcwidth(0x1F500)); // should be 2
So why not establish that functionality with an easy tweak that does not
interfere with anything?
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