当前位置:  开发笔记 > 编程语言 > 正文

这个简单的C++程序使用<locale>是否正确?

如何解决《这个简单的C++程序使用<locale>是否正确?》经验,为你挑选了1个好方法。

这个代码似乎在(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



1> T.C...:

看起来这是由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.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有