关于so​​laris (x86)上的std::basic_string的一些困惑

发布于 2024-12-15 03:41:07 字数 863 浏览 1 评论 0原文

关于so​​laris (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尾戒 2024-12-22 03:41:07

-fshort-wchar 的文档 读到,

-fshort-wchar

wchar_t 的基础类型覆盖为 short unsigned int,而不是目标的默认类型。此选项对于构建在 WINE 下运行的程序很有用。

警告: -fshort-wchar 开关导致 GCC 生成的代码与没有该开关生成的代码不二进制兼容。使用它来符合非默认应用程序二进制接口。

因此,似乎这个标志导致了观察到的差异,并且由于语言规范没有讨论这样的标志,因此该行为可以归类为实现定义的或未定义的。


作为旁注,在处理宽字符时,您应该使用 wcout 而不是 cout,因为 wcout 旨在处理宽字符:

  • < code>cout 是 basic_ostream 类型的对象。
  • wcoutbasic_ostream 类型的对象。

我认为,在这种情况下,问题不在于您用来打印值的内容,因为您告诉编译器将 wchar_t 视为 short unsigned int

The documentation of -fshort-wchar reads,

-fshort-wchar

Override the underlying type for wchar_t to be short unsigned int instead of the default for the target. This option is useful for building programs to run under WINE.

Warning: the -fshort-wchar switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.

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 of cout when dealing with wide-characters, as wcout is designed to handle wide-characters:

  • cout is an object of type basic_ostream<char>.
  • wcout is an object of type basic_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 as short unsigned int, anyway.

做个少女永远怀春 2024-12-22 03:41:07

标准库很可能不是用 --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.

樱花细雨 2024-12-22 03:41:07

看起来问题是 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 to wchar_t, which works correctly in other places (e.g. printing s[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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文