Hi Neven, I disagree with some of what's been said on this thread and think it could mislead others, so I'm piping up...
Greg Minshall wrote:
fwiw, for people writing code: a friend suggested something like this: first try user's configured locale (environment variables). if that fails, try the "C" locale. if that also fails, print out a warning, and continue to run: ---- /* modified from https://www.cl.cam.ac.uk/~mgk25/unicode.html */ if (!setlocale(LC_CTYPE, "") && !setlocale(LC_CTYPE, "C")) { fprintf(stderr, "Warning: Can't set the specified locale! " "Check LANG, LC_CTYPE, LC_ALL.\n");
That textual warning is incorrect because not just the specified locale was attempted. Looking at the URL, it doesn't suggest an attempt to fall back to the C locale.
/* but, keep going */
Neither does the web page suggest the program continue, but instead exit with an error status. int main() { if (!setlocale(LC_CTYPE, "")) { fprintf(stderr, "Can't set the specified locale! " "Check LANG, LC_CTYPE, LC_ALL.\n"); return 1; }
(though, of course, "continue to run" may not work in your case, i.e., Boost or other frameworks, etc.)
Or worse, it may continue to run but cause corruption of data.
A C program is in the "C" locale already when it reaches the main function
Agreed.
so I think there's no point to calling it again.
There isn't. setlocale(3p) says on error ‘the global locale shall not be changed’ so without a previous successful call to setlocale() it shall remain at the default ‘C’ locale which the C run-time has set up before entry to main(). This includes the more normal ‘setlocale(LC_ALL, "")’ as the man page says all error checking occurs up front.
But I definitely agree that to crash or to refuse to run depending on the locale is a serious bug.
No, to complain and stop is absolutely the right behaviour. The user has requested, through environment variables or lack thereof, the desired locale. Anything other than that could cause problems the program cannot anticipate and so it must not continue. Instead, it should clearly indicate the issue and exit with a non-zero status. -- Cheers, Ralph.