Bug 12859 - Output of floating point value changes global locale
Summary: Output of floating point value changes global locale
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Paolo Carlini
URL:
Keywords:
: 14970 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-10-31 15:59 UTC by pthomas
Modified: 2004-08-23 08:55 UTC (History)
3 users (show)

See Also:
Host: x86_64-suse-linux
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-02-16 04:52:28


Attachments
Testcase that shows the libstdc++ bug (193 bytes, text/plain)
2003-10-31 16:02 UTC, pthomas
Details

Note You need to log in before you can comment on or make changes to this bug.
Description pthomas 2003-10-31 15:59:36 UTC
Putting out a floating point value seems to change the global C locale. Just
compile and run the attached test program and you'll see that the last call
to isalpha returns false instead of the expected true. If you comment out the
line that outputs the fp value, isalpha returns true as expected.

3.3.1 and 3.3.2 also have the same bug that I consider quite nasty and 
unexpected.
Comment 1 pthomas 2003-10-31 16:02:22 UTC
Created attachment 5027 [details]
Testcase that shows the libstdc++ bug
Comment 2 Paolo Carlini 2003-10-31 20:39:06 UTC
Hi,

I can reproduce it and construct a pure "C" testcase in this sense: in v3
we use glibc uselocale assuming the the semantics is such that the below
outputs 0, 1024, 0, 1024 *not* 0, 1024, 0, 0 !!

#define _GNU_SOURCE 1
#include <locale.h>
#include <stdio.h>

int main()
{
  __locale_t    loc_new, loc_old;
  
  printf("%d\n", isalpha(0xE4));  // 0

  setlocale ( LC_ALL, "de_DE" );
  printf("%d\n", isalpha(0xE4));  // 1024

  loc_new = newlocale(1 << LC_ALL, "C", 0);
  loc_old = uselocale(loc_new);

  printf("%d\n", isalpha(0xE4));  // 0
  
  uselocale(loc_old);

  printf("%d\n", isalpha(0xE4));  // 0 *not* 1024!

  freelocale(loc_new);
  return 0;
}

What are we doing wrong?? Why the (global) de_DE locale is not restored for
the current thread by the second uselocale?

I hope to sort this out before leaving to Nuremberg!
Paolo.
Comment 3 Paolo Carlini 2003-10-31 22:24:50 UTC
Another observation: actually, only the behavior of isalpha changes (and probably
that of all the other functions provided also in the *_l version by glibc2.3.*)
whereas the thread local locale is properly restored to de_DE after the formatted
output: try a sequence of 3 printf("%f\n", 1.2) instead and you will notice that
the third one, correctly (as prescribed by the de_DE locale, that is) prints the
decimal separator as a comma, not as a dot!
Comment 4 Paolo Carlini 2003-11-01 07:26:09 UTC
Hi again. I have got this reply from Roland McGrath (glibc maintainer):

>No confusion, just a bug.  I've fixed it.  The bug affected ctype functions
>after uselocale (LC_GLOBAL_LOCALE), but not other uses of locale data.
>
>
>Thanks,
>Roland

So, indeed, it's a glibc bug. Unfortunately, it will not be publically
corrected 'til glibc2.3.3, I'm afraid, and I don't think is in our policy
putting in workarounds, in such cases... I'm open to suggestions, however!

Paolo.
Comment 5 Jerry Quinn 2003-11-15 07:51:04 UTC
If we get floating point printing in place that doesn't rely on sprintf anymore,
this issue should disappear for float output.  Mucking with the global locale is
only necessary to ensure correct sprintf behavior.
Comment 6 Paolo Carlini 2004-04-15 20:14:50 UTC
*** Bug 14970 has been marked as a duplicate of this bug. ***
Comment 7 Paolo Carlini 2004-08-23 08:55:40 UTC
I guess we can close this one: 17140 tracks the specific issue with new floating
point output code.