Date: Tue, 08 Dec 2020 19:18:40 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 251674] libc++: std::wcout does not use global locale set via setlocale() Message-ID: <bug-251674-227-7bowiunJQ1@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-251674-227@https.bugs.freebsd.org/bugzilla/> References: <bug-251674-227@https.bugs.freebsd.org/bugzilla/>
index | next in thread | previous in thread | raw e-mail
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251674 --- Comment #11 from Dimitry Andric <dim@FreeBSD.org> --- (In reply to Yuri Pankov from comment #9) > So libstdc++'s wcout being affected by setlocale() call is just an > implementation choice, the one that libc++ didn't make? Apparently, although that documentation link from libstdc++ that I pasted doesn't really tell anything about it, except maybe the part: > Locale initialization: at what point does _S_classic, _S_global get > initialized? Can named locales assume this initialization has already taken > place? but it seems this doc article is very old. Looking at libstdc++'s implementation, it appears they initialize a default locale() object here: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/src/c%2B%2B98/ios_locale.cc#l44 // Called only by basic_ios<>::init. void ios_base::_M_init() throw() { // NB: May be called more than once _M_precision = 6; _M_width = 0; _M_flags = skipws | dec; _M_ios_locale = locale(); } This default locale() object is constructed in https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/src/c%2B%2B98/locale_init.cc, but it seems like a separate copy of a C-like locale by default, e.g it has: void locale::_S_initialize_once() throw() { // 2 references. // One reference for _S_classic, one for _S_global _S_classic = new (&c_locale_impl) _Impl(2); _S_global = _S_classic; new (&c_locale) locale(_S_classic); } and the _Impl constructor is: // Construct "C" _Impl. locale::_Impl:: _Impl(size_t __refs) throw() : _M_refcount(__refs), _M_facets(0), _M_facets_size(num_facets), _M_caches(0), _M_names(0) { _M_facets = new (&facet_vec) const facet*[_M_facets_size](); _M_caches = new (&cache_vec) const facet*[_M_facets_size](); // Name the categories. _M_names = new (&name_vec) char*[_S_categories_size](); _M_names[0] = new (&name_c[0]) char[2]; std::memcpy(_M_names[0], locale::facet::_S_get_c_name(), 2); // This is needed as presently the C++ version of "C" locales // != data in the underlying locale model for __timepunct, // numpunct, and moneypunct. Also, the "C" locales must be // constructed in a way such that they are pre-allocated. // NB: Set locale::facets(ref) count to one so that each individual // facet is not destroyed when the locale (and thus locale::_Impl) is // destroyed. _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1)); _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1)); ... much more of this ... } So I think what you're seeing with libstdc++ is intentional, in the sense that they have a default locale which is sort-of the same as the default C locale (or even C.UTF-8). The only call to setlocale() in that .cc file is when you call std::locale::global(), as indicated in the docs. -- You are receiving this mail because: You are the assignee for the bug.help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-251674-227-7bowiunJQ1>
