Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 30 Nov 2020 09:48:06 -0500
From: Rich Felker <dalias@...c.org>
To: Samuel Holland <samuel@...lland.org>
Cc: musl@...ts.openwall.com,
	Érico Nogueira <ericonr@...root.org>,
	Dong Brett <brett.browning.dong@...il.com>
Subject: Re: Question on C++ locale

On Mon, Nov 30, 2020 at 08:39:18AM -0600, Samuel Holland wrote:
> On 11/30/20 7:44 AM, Érico Nogueira wrote:
> > On Mon Nov 30, 2020 at 8:35 AM -03, Szabolcs Nagy wrote:
> >> * Dong Brett <brett.browning.dong@...il.com> [2020-11-30 18:41:33
> >> +0800]:
> >>> However, the following C++ code does not work (our software uses std::locale in C++ standard library for locale related stuff):
> >>> #include <langinfo.h>
> >>> #include <locale.h>
> >>> #include <locale>
> >>> using namespace std;
> >>> int main()
> >>> {
> >>>     std::locale::global(locale(""));
> >>>     initscr();
> >>>     printw("LC_ALL: %s\n", setlocale(LC_ALL, NULL));
> >>>     printw("C++ locale: %s\n", locale().name().c_str());
> >>>     printw("CODESET: %s\n", nl_langinfo(CODESET));
> >>>     printw("Hello, world!\n");
> >>>     printw("你好,世界!\n");
> >>>     refresh();
> >>>     getch();
> >>>     endwin();
> >>>     return 0;
> >>> }
> >>
> >> fwiw for me even the first line fails.
> >> i don't know how c++ locales are supposed to work.
> > 
> > From [1], it seems that C++ locales are supposed to affect the global
> > locale as well, so they should call setlocale() when appropriate.
> > 
> > - [1] https://www.cplusplus.com/reference/locale/locale/
> > 
> > Unfortunately, I assume libstdc++ uses their generic locale support on
> > musl...  From gcc-10.2.0/libstdc++-v3/config/locale/generic/c_locale.cc:
> > 
> >   void
> >   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
> > 				    __c_locale)
> >   {
> >     // Currently, the generic model only supports the "C" locale.
> >     // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html
> >     __cloc = 0;
> >     if (strcmp(__s, "C"))
> >       __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
> > 			    "name not valid"));
> >   }
> > 
> 
> I don't know for sure that it's the right thing to do, but I have been patching
> out that error for the last several years[1] and so far I have not noticed any
> negative effects. Adelie, which is very thorough about testing, has also carried
> the patch for a while[2].
> 
> Samuel
> 
> [1]:
> https://github.com/smaeul/portage/blob/c744774a/patches/sys-devel/gcc/gcc-5.4.0-locale.patch
> [2]: https://code.foxkit.us/adelie/packages/-/commit/d09b437d

That libstdc++ code is definitely wrong and should be removed, but I'm
not sure what other bugs in libstdc++ might be hiding behind it. Next
time you find something like this please send the patches here for
inclusion in mcm and proper bug reporting to GCC.

Note that the message cited in the comment is just wrong; generic
should work fine with the modern POSIX locale API
(newlocale/uselocale) which I was nearly sure libstdc++ was already
using. If this isn't the case we need to fix that.

In any case, setlocale should be used directly in the above code, not
C++ locale framework, since curses is a C library whose behavior is
defined by the locale set through the C mechanisms not whatever wacky
stuff libstdc++ does.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.