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