关于solaris(x86)上的std :: basic_string的一些难题
#include <iostream>
#include <string>
int main()
{
const wchar_t* s = L"abcdef";
std::wstring ws(s, s+6);
for(int i = 0; i < ws.size(); ++i)
{
std::cout << ws[i] << std::endl;
}
return 0;
}
运行结果是:
97
99
101
0
0
0
为什么不是
97
98
99
100
101
102
代码
#include <iostream>
#include <string>
int main()
{
const wchar_t* s = L"abcdef";
std::wstring ws;
ws.resize(6);
for(int i = 0; i < ws.size(); ++i)
{
std::cout << (ws[i] = s[i]) << std::endl;
}
return 0;
}
可以获得预期的结果。
我使用gcc 3.4.6
,构建命令是g++ -fshort-wchar stringtest.cpp
。任何一个人都可以表达出来吗?
答案 0 :(得分:5)
-fshort-wchar
的文档读取,
-fshort-wchar
将
wchar_t
的基础类型覆盖为short unsigned int
,而不是目标的默认值。此选项对于构建在WINE下运行的程序非常有用。警告: -fshort-wchar开关导致GCC生成的代码与不使用该开关生成的代码不是二进制兼容的。使用它来符合非默认应用程序二进制接口。
所以看起来这个标志导致了观察到的差异,并且由于语言规范没有讨论这样的标志,所以行为可以分为实现定义或未定义。
作为旁注,在处理宽字符时,您应该使用wcout
而不是cout
,因为wcout
旨在处理宽字符:
cout
是basic_ostream<char>
类型的对象。wcout
是basic_ostream<wchar_t>
类型的对象。在这种情况下,问题不在于你用来打印值的问题,因为你告诉编译器无论如何都要将wchar_t
视为short unsigned int
。
答案 1 :(得分:2)
标准库很可能不会使用--short-wchar
进行编译。此标志会更改ABI,但这不会被检测到,因为名称修改不会更改。
答案 2 :(得分:0)
看起来问题是ws[i]
给出了错误的结果;当我查看原始内存时,字符串似乎包含预期的数据。令人困惑的是为什么会发生这种情况;据我所知,operator[]
只是取消引用指向wchar_t
的指针,该指针在其他位置正常工作(例如,在第二个示例中打印s[i]
)。问题也出现在更新版本的GCC(我试过4.6.1)和Linux上。
您可以使用*(ws.begin() + i)
来解决此问题。