This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
locale class is not working under Solaris
- From: Tamas Sarlos <stamas at csillag dot ilab dot sztaki dot hu>
- To: libstdc++ at gcc dot gnu dot org
- Cc: steve at smc dot vnet dot net
- Date: Thu, 25 Sep 2003 21:53:49 +0200 (CEST)
- Subject: locale class is not working under Solaris
Hi,
This might be an already answered question, but I couldn't find it.
It seems to me as if the ctype functions of the C++ locale class doesn't
work under Solaris. Moreover, the behaviour of isalpha(_CharT, const
locale&) and alike depends on the globally set C locale.
Here is a small program to check it with the German ö (o+umlaut):
[stamas@sun stamas]$ cat ./testlocale.cc
#include <iostream>
#include <locale>
using namespace std;
void cxx_locale( int i, const char *locale_name ) {
locale loc(locale_name);
char c = i;
cout << "C++ locale=" << loc.name() << " "
<< "character=" << c << " code=" << i << " "
<< "isprint=" << isprint(c,loc) << " "
<< "isalpha=" << isalpha(c,loc) << endl;
}
void c_locale( int i, const char *locale_name ) {
char *ret;
char c = i;
if( (ret=setlocale(LC_ALL,locale_name)) )
cout << "Global C locale set to " << ret << "." << endl;
else
cerr << "Can't set C locale to " << locale_name << "!" << endl;
cout << "C locale=" << ret << " "
<< "character=" << c << " code=" << i << " "
<< "isprint=" << (isprint(c) ? "true" : "false") << " "
<< "isalpha=" << (isalpha(c) ? "true" : "false") << endl;
}
int main(void) {
char german[] = "de_DE";
int o_umlaut = 246;
cout << boolalpha;
cxx_locale(o_umlaut, german);
c_locale (o_umlaut, german);
cxx_locale(o_umlaut, german);
c_locale (o_umlaut, "C" );
cxx_locale(o_umlaut, german);
try {
cxx_locale(o_umlaut, "nosuch");
}
catch(...) {
cerr << "Exception!" << endl;
}
// abort();
return 0;
}
-- End of program listing. --
Running this program on a Redhat 9 Linux PC with g++ 3.2 gives the expected
results.
[stamas@ibm19 stamas]$ uname -a
Linux ibm19 2.4.20-19.9 #1 Tue Jul 15 17:18:13 EDT 2003 i686 i686 i386 GNU/Linux
[stamas@ibm19 stamas]$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
[stamas@ibm19 stamas]$ g++ -Wall -o testlocale testlocale.cc
[stamas@ibm19 stamas]$ ./testlocale
C++ locale=de_DE character=ö code=246 isprint=true isalpha=true
Global C locale set to de_DE.
C locale=de_DE character=ö code=246 isprint=true isalpha=true
C++ locale=de_DE character=ö code=246 isprint=true isalpha=true
Global C locale set to C.
C locale=C character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=true isalpha=true
Exception!
[stamas@ibm19 stamas]$
However, on the same hardware config running the x86 version of Solaris 9,
I get:
(The compiler is from the SMCgcc package from http://sunfreeware.com/)
(Forgive me for the sun hostname for a PC, it was not me who chose it.)
[stamas@sun stamas]$ uname -a
SunOS sun 5.9 Generic_112234-08 i86pc i386 i86pc Solaris
[stamas@sun stamas]$ g++ -v
Reading specs from /usr/local/lib/gcc-lib/i386-pc-solaris2.9/3.2.3/specs
Configured with: ../configure --disable-nls --with-as=/usr/ccs/bin/as
--with-ld=/usr/ccs/bin/ld
Thread model: posix
gcc version 3.2.3
[stamas@sun stamas]$ g++ -Wall -o testlocale testlocale.cc
[stamas@sun stamas]$ ./testlocale
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
Global C locale set to de_DE.
C locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
Global C locale set to C.
C locale=C character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=nosuch character=ö code=246 isprint=false isalpha=false
As you can see, the de_DE locale is neither working in C or C++ because
of the signed char. However libstdc++ accepts the nonexistent "nosuch" locale,
and no exception is thrown.
Furthermore recompiling the program with unsigned chars, I get rather
strange results:
[stamas@sun stamas]$ g++ -funsigned-char -Wall -o testlocale testlocale.cc
[stamas@sun stamas]$ ./testlocale
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
Global C locale set to de_DE.
C locale=de_DE character=ö code=246 isprint=true isalpha=true
C++ locale=de_DE character=ö code=246 isprint=true isalpha=true
Global C locale set to C.
C locale=C character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=nosuch character=ö code=246 isprint=false isalpha=false
[stamas@sun stamas]$
This output proves, that the de_DE C locale is indeed working.
(See the line:
C locale=de_DE character=ö code=246 isprint=true isalpha=true
)
But it is rather surprising that the de_DE C++ locale object seems to work
according to the last C setlocale() call.
(See the different
C++ locale=de_DE character=ö code=246 isprint=true isalpha=true
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
lines)
I also reran the testlocale.cc program on a Solaris 8 Sparc box:
regeczi@sun01:~$> uname -a
SunOS sun01 5.8 Generic_108528-14 sun4u sparc
regeczi@sun01:~$> g++ -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.2/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as
--with-ld=/usr/ccs/bin/ld --disable-nls
Thread model: posix
gcc version 3.2
regeczi@sun01:~$>
The result were exactly the same as for the Intel Solaris.
Unfortunately, I have no access to a Solaris with the newest gcc compiler.
As far as I know Solaris implements the various locales in separate .so objects.
If I uncommented the abort(); just before the end of main, I could see
traces of /usr/lib/locale/de_DE.so.2:
[stamas@sun stamas]$ g++ -funsigned-char -Wall -o testlocale testlocale.cc
[stamas@sun stamas]$ ./testlocale
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
Global C locale set to de_DE.
C locale=de_DE character=ö code=246 isprint=true isalpha=true
C++ locale=de_DE character=ö code=246 isprint=true isalpha=true
Global C locale set to C.
C locale=C character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=nosuch character=ö code=246 isprint=false isalpha=false
Abort (core dumped)
[stamas@sun stamas]$ gdb testlocale core
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-pc-solaris2.9"...
(no debugging symbols found)...
Core was generated by ./testlocale'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/local/lib/libstdc++.so.5...done.
Loaded symbols for /usr/local/lib/libstdc++.so.5
Reading symbols from /usr/lib/libm.so.1...done.
Loaded symbols for /usr/lib/libm.so.1
Reading symbols from /usr/local/lib/libgcc_s.so.1...done.
Loaded symbols for /usr/local/lib/libgcc_s.so.1
Reading symbols from /usr/lib/libc.so.1...done.
Loaded symbols for /usr/lib/libc.so.1
Reading symbols from /usr/lib/libdl.so.1...done.
Loaded symbols for /usr/lib/libdl.so.1
Reading symbols from /usr/lib/locale/de_DE/de_DE.so.2...done.
Loaded symbols for /usr/lib/locale/de_DE/de_DE.so.2
#0 0xdda81b76 in _libc_kill () from /usr/lib/libc.so.1
However if I went further and put a comment before the two c_locale calls
(so that setlocale is not called), I get:
[stamas@sun stamas]$ g++ -funsigned-char -Wall -o testlocale testlocale.cc
[stamas@sun stamas]$ ./testlocale
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=de_DE character=ö code=246 isprint=false isalpha=false
C++ locale=nosuch character=ö code=246 isprint=false isalpha=false
Abort (core dumped)
[stamas@sun stamas]$ gdb testlocale core
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-pc-solaris2.9"...
(no debugging symbols found)...
Core was generated by ./testlocale'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/local/lib/libstdc++.so.5...done.
Loaded symbols for /usr/local/lib/libstdc++.so.5
Reading symbols from /usr/lib/libm.so.1...done.
Loaded symbols for /usr/lib/libm.so.1
Reading symbols from /usr/local/lib/libgcc_s.so.1...done.
Loaded symbols for /usr/local/lib/libgcc_s.so.1
Reading symbols from /usr/lib/libc.so.1...done.
Loaded symbols for /usr/lib/libc.so.1
Reading symbols from /usr/lib/libdl.so.1...done.
Loaded symbols for /usr/lib/libdl.so.1
#0 0xdda81b76 in _libc_kill () from /usr/lib/libc.so.1
As you can see, libstdc++ didn't try to/manage to load the proper shared
object for the locale (Setting LD_LIBRARY_PATH doesn't help either.)
Could anyone please give some information as to what is causing this
strange behaviour of the locale class under Solaris?
Regars,
Tamas Sarlos,
Budapest, Hungary