Created attachment 44110 [details] Source code and test output results showing error Dear Bug Team, I just recently upgraded using "apt" my Ubuntu 16.04 system and gcc was upgraded from 6.2.0 to 6.4.0 which introduced the following bug. In the attached archive is a program "testlocale.cpp" which requires only gcc-supplied header files. The command line to compile it and execute it is in the comments at the top of the file. In essence, it tests each facet of three locales (on my system "en_US.utf8", "pt_BR.utf8" and "C" locales. All worked perfectly in g++ 6.2.0. As of g++ 6.4.0, all of the facets, except the "moneypunct" facet work properly (see line 134). Here is my information: Linux version $ uname -a Linux asusubuntu16 4.13.0-41-generic #46~16.04.1-Ubuntu SMP Thu May 3 10:06:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux Compiler version $ gcc --version gcc (Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compile command: $ g++ -std=c++14 -m64 testlocale.cpp -static -o testlocale Run command: $ ./testlocale > testlocale.out Attached is a test output generated by gcc 6.4.0 on my system. Of course, you can test it on your system yourself and try to duplicate the error. Best regards, Tom Straub
Sorry, wrong compiler included in post, here is the right one: $ g++ --version g++ (Ubuntu 6.4.0-17ubuntu1~16.04) 6.4.0 20180424 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
It works fine for me with any version of GCC, including 6.4.0 Testing 'moneypunct' Facet: --> Setting locale 'pt_BR.utf8' Natl Currency Symbol = 'R$' Intl Currency Symbol = 'BRL ' Natl Positive Sign = '' Intl Positive Sign = '' Natl Positive Format = { sign, symbol, space, value } Intl Positive Format = { sign, symbol, space, value } Natl Negative Sign = '-' Natl Negative Format = { sign, symbol, space, value } Intl Negative Sign = '-' Intl Negative Format = { sign, symbol, space, value } Natl Decimal Point = ',' Intl Decimal Point = ',' Natl Thousands Separator = '.' Intl Thousands Separator = '.' Natl Fractional Digits = '2' Intl Fractional Digits = '2' Natl Grouping Length [0] = 3 digits Natl Grouping Length [1] = 3 digits Intl Grouping Length [0] = 3 digits Intl Grouping Length [1] = 3 digits Are you sure something else didn't change on your system at the same time? The C++ library just parses the locale definition data on your system, that data comes from glibc not from GCC.
Oh I take it back, when I use -static I can reproduce the problem.
Reduced: #include <iostream> #include <locale> using namespace std; void test(std::locale loc) { cout << "--> Setting locale '" << loc.name() << "'\n"; const moneypunct<char, true> & l_facMoneyIntl = use_facet<moneypunct<char, true> >(loc); const moneypunct<char, false> & l_facMoneyNatl = use_facet<moneypunct<char, false> >(loc); cout << "Natl Currency Symbol = '"; cout << l_facMoneyNatl.curr_symbol(); cout << "'" << "\n"; cout << "Intl Currency Symbol = '"; cout << l_facMoneyIntl.curr_symbol(); cout << "'" << "\n"; cout << "\n"; } int main(int argc, char** argv) { locale global (""); // locale::global(global); test(locale(argc == 1 ? "pt_BR.utf8" : argv[1])); test(global); test(locale("C")); } Without -static this produces something like: --> Setting locale 'pt_BR.utf8' Natl Currency Symbol = 'R$' Intl Currency Symbol = 'BRL ' --> Setting locale 'LC_CTYPE=en_GB.UTF-8;LC_NUMERIC=en_GB.UTF-8;LC_TIME=en_GB.UTF-8;LC_COLLATE=C;LC_MONETARY=en_GB.UTF-8;LC_MESSAGES=en_GB.UTF-8;LC_PAPER=en_GB.UTF-8;LC_NAME=en_GB.UTF-8;LC_ADDRESS=en_GB.UTF-8;LC_TELEPHONE=en_GB.UTF-8;LC_MEASUREMENT=en_GB.UTF-8;LC_IDENTIFICATION=en_GB.UTF-8' Natl Currency Symbol = '£' Intl Currency Symbol = 'GBP ' --> Setting locale 'C' Natl Currency Symbol = '' Intl Currency Symbol = '' But with -static the fields are all blank: --> Setting locale 'pt_BR.utf8' Natl Currency Symbol = '' Intl Currency Symbol = '' --> Setting locale 'LC_CTYPE=en_GB.UTF-8;LC_NUMERIC=en_GB.UTF-8;LC_TIME=en_GB.UTF-8;LC_COLLATE=C;LC_MONETARY=en_GB.UTF-8;LC_MESSAGES=en_GB.UTF-8;LC_PAPER=en_GB.UTF-8;LC_NAME=en_GB.UTF-8;LC_ADDRESS=en_GB.UTF-8;LC_TELEPHONE=en_GB.UTF-8;LC_MEASUREMENT=en_GB.UTF-8;LC_IDENTIFICATION=en_GB.UTF-8' Natl Currency Symbol = '' Intl Currency Symbol = '' --> Setting locale 'C' Natl Currency Symbol = '' Intl Currency Symbol = '' I can reproduce this with any version tested (back to 4.3.6).
Hi Johnathon, Okay, thanks for confirming. I didn't realize it was such as old bug. You're right, I just recently switched over to using -static (got tired of the library mismatches with multiple gcc versions on my system). Best, Tom
This isn't a libstdc++ bug, I get the same with a pure C program: $ cat loc.c #include <locale.h> #include <langinfo.h> #include <stdio.h> int main() { locale_t loc = newlocale(1 << LC_ALL, "en_US.UTF-8", 0); const char* ccurr = nl_langinfo_l(CURRENCY_SYMBOL, loc); printf("Currency symbol: %s\n", ccurr); return 0; } $ gcc -D_GNU_SOURCE loc.c $ ./a.out Currency symbol: $ $ gcc -D_GNU_SOURCE loc.c -static $ ./a.out Currency symbol: So this seems to be a glibc problem.
Hi Jonathan, Thanks for really tracking that down. Looks like a really deep and subtle bug. I hope somebody knows where to look to fix it in the glibc code. Best, Tom
I don't think we can do anything to fix this in libstdc++ so I've reported it to glibc: https://sourceware.org/bugzilla/show_bug.cgi?id=23164
*** Bug 71641 has been marked as a duplicate of this bug. ***