Incorrect information about setlocale behavior on native windows

Kirill Makurin <[email protected]>
Newsgroups gmane.comp.lib.gnulib.bugs
Message-ID <WPQ2VVLiwKAu4TbQnFdN7XcKAIHpFzTfLODJwDReqv1wc2D88aNt4_JGbs6myGFArJ5b1FgE4rjQVXKD4w7c5mQ6b1BQiBgHE0U3D3MBHDU=@proton.me>
Hello,

[1] describes the following behavior:

```
On Windows platforms (excluding Cygwin) and Cygwin 1.5.x, setlocale(LC_ALL,name) succeeds and sets the LC_CTYPE category to ‘C’ when it does not support the encoding, instead of failing. 
```

The incorrect part is that it sets LC_CTYPE category to "C"; the following example can be used to prove it wrong:

```
#include <locale.h>
#include <stdio.h>

int main (void) {
  // setlocale (LC_ALL, "English_United States.1252");
  // printf ("%s\n", setlocale (LC_ALL, NULL));
  setlocale (LC_ALL, "English_United States.10001");
  printf ("%s\n", setlocale (LC_ALL, NULL));
  return 0;
}
```

If I run this code, I get the following output:

```
LC_COLLATE=English_United States.10001;LC_CTYPE=C;LC_MONETARY=English_United States.10001;LC_NUMERIC=English_United States.10001;LC_TIME=English_United States.10001
```

Here, you can see that LC_CTYPE category in fact is set to "C". Now, let's uncomment the first two lines of code and see what happens:

```
English_United States.1252
LC_COLLATE=English_United States.10001;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.10001;LC_NUMERIC=English_United States.10001;LC_TIME=English_United States.10001
```

Now you can see that after second call to `setlocale`, LC_CTYPE category is set to "English_United States.1252", not "C".

What does it mean? Instead of setting LC_CTYPE category to "C", it simply did not change setting for LC_CTYPE category. I believe that original impression of setting LC_CTYPE to "C" comes from "C" being the active locale before problematic `setlocale` call. I had the same impression until I noticed strange behavior in some of tests in my project.

If you replace LC_ALL with LC_CTYPE in the example, the problematic call to `setlocale` will actually fail. This behavior provides a way to workaround problematic case: before calling `setlocale` with LC_ALL, call it with LC_CTYPE; if call succeeds, it should be safe to call it with LC_ALL.

- Kirill Makurin

[1] https://www.gnu.org/software/gnulib/manual/html_node/setlocale.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.