这个代码似乎在(ubuntu可信赖)版本的gcc和clang中运行正常,并且在Win 7中通过mingw运行...最近我升级到Wily并且使用clang崩溃在这里进行构建.
#include#include #include int main() { std::cout << "The locale is '" << std::locale("").name() << "'" << std::endl; }
有时它是一个乱码的字符串Aborted: Core dumped
,有时是它的invalid free
.
$ ./a.out The locale is 'en_US.UTF-8QX???X??????0?????P?????\?(??\?(??\?(??h??t?????????????y???????????????????en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_UP????`?????????????????????????p???????????@??????????????`?????????????p????????????????????@??@??@??`????????p????????????0??P??p???qp??!en_US.UTF-8Q?[?????\?(??\?(??\?(???????????@?? ?????P?????0?????P?????\?(??\?(??\?(?????????????????????(??4??@??L??en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8!?v[??????????????@?? ?????P?????0?????P?????\?(??\?(???(??h??t??????????????????????????????en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8!??[?? ????[???????7????7??.,!!x?[??!??[??!?[??@???????????@?? ?????P?????0?????P?????\?(??\?(??\?(??(??4??@??L??X??d??p??|????????????n_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8?Aborted (core dumped) $ ./a.out The locale is 'en_US.UTF-8QX\%?QX\%?Q?G?0H??H?PI??I?\:|?Q\D|?Q\>|?QhK?tK??K??K??K??K??Q?K??K??K??K??K??K?en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8? *** Error in `./a.out': free(): invalid pointer: 0x0000000000b04a98 *** Aborted (core dumped)
(上述两个节目输出都大大缩短,或者它们不适合这个问题.)
我也在Coliru上也获得了无效免费.
但这与cppreference上的示例代码非常相似:
#include#include #include int main() { std::wcout << "User-preferred locale setting is " << std::locale("").name().c_str() << '\n'; // on startup, the global locale is the "C" locale std::wcout << 1000.01 << '\n'; // replace the C++ global locale as well as the C locale with the user-preferred locale std::locale::global(std::locale("")); // use the new global locale for future wide character output std::wcout.imbue(std::locale()); // output the same number again std::wcout << 1000.01 << '\n'; }
实际上代码崩溃了Coliru ......:facepalm:
更多 来自Coliru的类似代码的崩溃.
这是clang使用的c ++库中的错误,还是这个代码有缺陷?
另请注意:这些崩溃似乎仅限于C++ api,如果您使用的
话似乎工作正常,那么它可能只是C++绑定中的一些微不足道的问题?
变化使用setlocale
:1 2 3
看起来这是由libstdc ++的ABI变化引起的basic_string
,这是C++ 11一致性所需要的.为了管理这种转换,GCC添加了abi_tag
属性,该属性更改了函数的错位名称,以便可以区分新旧ABI的函数,即使更改不会影响错位名称(例如函数的返回类型) ).
这段代码
#include#include int main() { std::locale().name(); }
在GCC上发出一个调用 _ZNKSt6locale4nameB5cxx11Ev
,该调用解析为std::locale::name[abi:cxx11]() const
,并返回一个带有新ABI的SSO字符串.
另一方面,Clang 不支持该abi_tag
属性,并且发出一个调用 _ZNKSt6locale4nameEv
,该函数简单地解析std::locale::name() const
- 这是返回COW字符串的版本(旧的ABI).
最终结果是程序在使用Clang编译时最终尝试使用COW字符串作为SSO字符串.随之而来的是浩劫.
显而易见的解决方法是通过强制旧的ABI -D_GLIBCXX_USE_CXX11_ABI=0
.