www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2026/06/01/11:35:00

DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 651FYxNS3649247
Authentication-Results: delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com
Authentication-Results: delorie.com; spf=pass smtp.mailfrom=cygwin.com
DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 651FYxNS3649247
Authentication-Results: delorie.com;
dkim=pass (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=JbFrqpE1
X-Recipient: archive-cygwin AT delorie DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B6834BA2E23
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
s=default; t=1780328098;
bh=gD2n4JmUvl/D37v2z4vtTRlzUi/OIvZUuzTnlW34cBE=;
h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post:
List-Help:List-Subscribe:From:Reply-To:From;
b=JbFrqpE13VPExxpugzRLXTKAWmrRCLtTx3meOoM+0z8Ql7mIWke7V2FvwL2nTARFu
N/ZKyPU/lYoQR0KUeYuaFpmsnG7UlNM+Aid+4N4+KnLcicMAIRMYI7M/JPuoWYv2Al
3J5OY8o6eMFGgTlXA3V3JowJkf1cZ9vPJCdTprJU=
X-Original-To: cygwin AT cygwin DOT com
Delivered-To: cygwin AT cygwin DOT com
DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C156E4BA2E11
ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C156E4BA2E11
ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780328080; cv=none;
b=E0gC/Dh9tAzbkpWVGtL4KCIzbuzReq8O6HMmDGwoCf04RuUxmpKNWUmInAXiBfGQsbZsnJXUOfZtiASsouU0jzp4uZ0FVBPdgp//kUCdZWme7eVGO6iT6/EccyiQjSHQxy4chTu1wQN/EXtvrUPpcHn6c7FFU2fdC+fZysCbKWY=
ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key;
t=1780328080; c=relaxed/simple;
bh=kmKBCCgc+6Ln5RBcF3f9IapCKQ9CsnOKmKB40FjSEsY=;
h=DKIM-Signature:To:From:Subject:Message-ID:Date:MIME-Version;
b=r2Mz6aTE+uux2yHaqjNIUr4rnp+vNYs994Z6+T5trdl+Pp+ze7k0esVxUV0EmCejBMIiMTUz31zYv7120Y5UKpWJAixqs7X5njWanPmllZWVfLKqP5o+viIwYiZuq2Sa0PsoIdRjlmfQr+Dj73YiumRXE4ZYfihSRk1v+PuL6fk=
ARC-Authentication-Results: i=1; sourceware.org;
dkim=pass (2048-bit key, unprotected)
header.d=wisemo.com header.i=@wisemo.com header.a=rsa-sha256 header.s=v2016
header.b=MCVisYme
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C156E4BA2E11
To: cygwin AT cygwin DOT com
Subject: Thoughts on the wcwidth confusion
Organization: WiseMo A/S
Message-ID: <19c6f9b4-5f09-6929-891c-d25ebe48af82@wisemo.com>
Date: Mon, 1 Jun 2026 17:34:35 +0200
X-Mailer: Epyrus/2.2.0
MIME-Version: 1.0
X-BeenThere: cygwin AT cygwin DOT com
X-Mailman-Version: 2.1.30
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-request AT cygwin DOT com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
From: Jakob Bohm via Cygwin <cygwin AT cygwin DOT com>
Reply-To: Jakob Bohm <jb-cygwin AT wisemo DOT com>
Sender: "Cygwin" <cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com>
X-MIME-Autoconverted: from base64 to 8bit by delorie.com id 651FYxNS3649247

Dear list,

Having read through the recent debate around the wcwidth() POSIX API,
wchar_t definitions, gcc-16 and cygwin, I have an idea not
mentioned in the list so far:

Using C17 types char32_t and char16_t, the situation can be
summarized as follows:

- Many, but not all POSIX systems define wchar_t as char32_t and thus
wint_t as uint_least32_t

- Win32 and thus Cygwin defines wchar_t as char16_t and thus wint_t as
uint_least16_t

- All systems considered treat wchar_t as unicode, with Win32 supporting
  UTF-16 since the NT 5.00 (Windows 2000).

- For char16_t/UTF-16, wcwidth() should use the high surrogate to
  determine the range of unicode symbols and return a width common to
  that range, then return 0 for the low surrogates, thereby allowing
  computation of string width without having to first assemble surrogates
  into full char32_t values.  Deciding if char32_t implementations should
  still lump groups of 4 Unicode rows for UTF-16 compatibility is up to
  each implementation.

A practical solution would be for Cygwin/newlib to provide new functions
c16width(), c32width(), c16swidth() and c32swidth(), each being the
explicit size equivalants of their wc and wcs similarly named functions.

Then wcwidth() can be a trivial inline alias of the explicit size
equivalent for the compile target by having the newlib header checking a
compiler or standard define indicating the chosen size of wchar_t.

// possible wchar.h snippet
//
// C17+ required
// For C2Y+ this should go in uchar.h
//
int c16width(char16_t c);
int c32width(char32_t c);
int c16swidth(const char16_t *s, size_t n);
int c32swidth(const char32_t *s, size_t n);

// ...

// This belongs in wchar.h for C1x- compat
//
#if SOMETHING_MEANING_16bit_WCHAR_T
inline int wcwidth(wchar_t c) {
   return c16width(c);
}
inline int wcswidth(const wchar_t *s, size_t n)
{
   return c16swidth(s, n);
}
#else
inline int wcwidth(wchar_t c) {
   return c32width(c);
}
inline int wcswidth(const wchar_t *s, size_t n)
{
   return c32swidth(s, n);
}
#endif


Enjoy

Jakob
-- 
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

-- 
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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019