3

As we all know, global data, like the locale settings affecting the numeric decimal point printf() and strtod() are using, is evil. Fortunately, MSVC++ 9 allows to use per-thread locales by a _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) call. Unfortunately, it seems that the localeconv() function does not notice this and still returns the global locale settings, e.g. localeconv()->decimal_point seems to always return the global locale setting before the _configthreadlocale() call. Is this a bug in the MSVC library or is this expected?

TIA Paavo

Mosty Mostacho
  • 42,742
  • 16
  • 96
  • 123
paavo256
  • 181
  • 3

4 Answers4

2

Despite the suggestion that this is expected behaviour from rubenvb, this is actually a bug that I ran into a while ago. I suspect rubenvb misread this part of the question:

Unfortunately, it seems that the localeconv() function does not notice this and still returns the global locale settings, e.g. localeconv()->decimal_point seems to always return the global locale setting before the _configthreadlocale() call.

The question wasn't intending on having localeconv() return on a per-thread basis before calling _configthreadlocale() as that would break the time continuum. The question was suggesting that the results of calling localeconv() after calling _configthreadlocale() are the same as calling it beforehand, which is unexpected. This essentially means Microsofts implementation of the C++ STL streams are fundamentally broken when using _configthreadlocale().

gigaplex
  • 471
  • 2
  • 8
0

The call to the _configthreadlocale sets the property, before the call, nothing special happens. So yes, this is expected behavior. You first must call this function, and then you can take advantage of thread-local locales.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
0

If setlocale is called before _configthreadlocale, then localconv will return the correct information for that setlocale call.

If setlocale is called after _configthreadlocale, then localconv will not return the correct information for that setlocale call.

Some output from a simple C test program compiled with VS Professional 2013.

_configthreadlocale aft-change=1
setlocale[LC_ALL] LC_COLLATE=ja-JP;LC_CTYPE=ja-JP;LC_MONETARY=fr-FR;LC_NUMERIC=ja-JP;LC_TIME=ja-JP
Main: decimal_point is '.'
Main: mon_decimal_point is ''
Main: int_curr_symbol is ''

mon_decimal_point should be ','.

int_curr_symbol should be 'EUR'.

0

The correct way to get per-thread locale info on Windows is:

_locale_t lct = _get_current_locale();
LogPrintf( "Main: decimal_point is '%s'", lct->locinfo->lconv->decimal_point );
LogPrintf( "Main: mon_decimal_point is '%s'", lct->locinfo->lconv->mon_decimal_point );
LogPrintf( "Main: int_curr_symbol is '%s'", lct->locinfo->lconv->int_curr_symbol );