_configthreadlocale only affects the thread-locale setting of the thread that 
calls it. It does not affect all threads in the process. Microsoft 
documentation says[1]:

```
When per-thread locale is disabled, any subsequent call to setlocale or 
_wsetlocale changes the locale of all threads that use the global locale. When 
per-thread locale is enabled, setlocale or _wsetlocale only affects the current 
thread's locale.
```

For example, uselocale (with locale != `LC_GLOBAL_LOCALE`) could 
(oversimplified)

```
_configthreadlocale (_ENABLE_PER_THREAD_LOCALE);
setlocale (LC_*, locale_string);
```

This will enable per-thread locale in the calling thread and set its locale.

In order to switch back to global locale (e.g. with 
`uselocale(LC_GLOBAL_LOCALE)`) you can simply

```
_configthreadlocale (_DISABLE_PER_THREAD_LOCALE);
```

The unfortunate thing about _configthreadlocale is that you use 
setlocale/_wsetlocale to set thread's locale. It also means that if current 
thread uses per-thread locale, setlocale(LC_*, NULL) will return locale for the 
current thread and not global locale.

This way, if we want to make sure that setlocale changes/quires global locale, 
we would need to:

1. Save current _configthreadlocale setting
2. Change it to _DISABLE_PER_THREAD_LOCALE
3. Change/query global locale
4. Restore _configthreadlocale setting to value saved in step 1

- Kirill Makurin

[1] 
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/configthreadlocale

________________________________
From: Bruno Haible <[email protected]>
Sent: Wednesday, September 17, 2025 7:07 PM
To: Kirill Makurin <[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: native Windows locale topics

Hi Kirill,

> This is some interesting information. In the recent months I was working on 
> windows-specific implementation of POSIX newlocale/uselocale functions as 
> well as replacements for locale-related CRT functions.

When you do that, please use Gnulib's test suite, to make sure that
patches you submit to mingw-w64 are of high quality. Too often I've
made the experience that when a C runtime library adds a new feature,
it's buggy in the first release and it needs another release to
stabilize — and so I need to add yet another workaround to Gnulib,
for yet another silly bug. All that because programmers did not properly
test the code that they submitted.

> I have collected some information about locale-related features in Windows 
> API and CRT. I have posted it to mingw-w64 list and you can find it here if 
> you're interested[1].
> [1] https://sourceforge.net/p/mingw-w64/mailman/message/59198335/

It's a good summary.

However, I disagree with this:
> msvcr80.dll introduced support for thread locales with _configthreadlocale[6] 
> function.
> Makes implementing POSIX uselocale(3) easier :).

I don't think it makes implementing uselocale() easier. With
_configthreadlocale, the programmer has the choice between two
models:
  - All threads have the same locale,
  - Or: Each threads has its own locale.
Whereas with POSIX uselocale, a certain number of threads can
have their own locale each, and the other threads all have the
same locale.

Also, note that it takes several Windows '_locale_t' objects,
to represent a single POSIX 'locale_t' object.

> For example, are you aware that CRTs starting with msvcr80.dll (in particular 
> UCRT) natively support thread locales? I was wondering if libintl/libiconv 
> take this into account, because if not, this may lead to unexpected surprises.

GNU software cannot support _all_ of the possible operation
modes possible on Windows. It's intended to support the default
operation modes, and non-default ones only when there is a high
necessity (such as _setmode).

Bruno



Reply via email to