关于solaris (x86)上的std::basic_string的一些困惑
关于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
。任何人都可以解释一下吗?
Some puzzles about std::basic_string on solaris (x86)
#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;
}
The running result is:
97
99
101
0
0
0
Why is not
97
98
99
100
101
102
And the code
#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;
}
can get the expected result.
I use gcc 3.4.6
, build command is g++ -fshort-wchar stringtest.cpp
. Any one can give an expain?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
-fshort-wchar 的文档
读到,因此,似乎这个标志导致了观察到的差异,并且由于语言规范没有讨论这样的标志,因此该行为可以归类为实现定义的或未定义的。
作为旁注,在处理宽字符时,您应该使用
wcout
而不是cout
,因为wcout
旨在处理宽字符:basic_ostream
类型的对象。wcout
是basic_ostream
类型的对象。我认为,在这种情况下,问题不在于您用来打印值的内容,因为您告诉编译器将
wchar_t
视为short unsigned int
。The documentation of
-fshort-wchar
reads,So it seems that this flag is causing the observed discrepancy, and since the language specification doesn't talk about such flag, the behavior can be categorized as either implementation-defined or undefined.
As a sidenote, you should use
wcout
instead ofcout
when dealing with wide-characters, aswcout
is designed to handle wide-characters:cout
is an object of typebasic_ostream<char>
.wcout
is an object of typebasic_ostream<wchar_t>
.Thought, in this case, the problem is not what you use to print the value, as you're telling the compiler to treat
wchar_t
asshort unsigned int
, anyway.标准库很可能不是用
--short-wchar
编译的。该标志更改了 ABI,尽管这不会被检测到,因为名称修改不会更改。The standard library was most likely not compiled with
--short-wchar
. This flag changes the ABI, although this goes undetected because name mangling does not change.看起来问题是
ws[i]
给出了错误的结果;当我查看原始内存时,该字符串似乎包含预期的数据。为什么会发生这种情况真是令人费解;据我所知,operator[] 只是取消引用指向wchar_t
的指针,它在其他地方可以正常工作(例如打印s[i] 在你的第二个例子中)。该问题也出现在较新版本的 GCC(我尝试过 4.6.1)和 Linux 上。
您可以使用
*(ws.begin() + i)
来解决这个问题。It looks like the problem is
ws[i]
giving the wrong result; the string seems to contain the expected data when I look at the raw memory. It's quite baffling why this happens; as far as I can see,operator[]
is simply dereferencing a pointer towchar_t
, which works correctly in other places (e.g. printings[i]
in your second example). The problem also occurs on more recent versions of GCC (I tried 4.6.1), and on Linux.You can work around it by using
*(ws.begin() + i)
instead.