2011-11-14 7 views
4

いくつかのパズル:: Solaris上のbasic_string(x86の)いくつかのパズルのstdについて

#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

これは興味深いです。 Windowsでは、Visual C++ 2010で最初のコードサンプルが2番目の答えを示します。 – kol

+0

また、g ++は '-fshort-wchar'なしでビルドされたときに正しい結果を返します。それは問題を引き起こすオプションのようです。 –

+0

"-fshort-wchar:' wchar_t'の基になる型を、ターゲットのデフォルトではなく 'short unsigned int 'にオーバーライドします。 sizeof(wchar_t)とsizeof(短い符号なしint)を知ることは有益でしょう... – kol

答えて

5

-fshort-wcharの文書が読み込み、

-fshort-wchar

オーバーライドwchar_tのための基本となるタイプではなく、ターゲットのデフォルトのshort unsigned intされるように。このオプションは、WINEで実行するプログラムを構築する場合に便利です。

警告: -fshort-wcharスイッチを使用すると、スイッチなしで生成されたコードとバイナリ互換性のないコードが生成されます。それを使用して、デフォルト以外のアプリケーションバイナリインタフェースに準拠させます。

だから、このフラグが観察矛盾を引き起こしている、言語仕様は、このようなフラグについて話していないので、動作は実装定義または未定義のいずれかに分類することが可能と思われます。追記として


wcoutがワイド文字を処理するように設計されている、ワイド文字を扱うとき、あなたはwcoutの代わりcoutを使用する必要があります。

  • coutはタイプbasic_ostream<char>の目的です。
  • wcoutは、タイプbasic_ostream<wchar_t>のオブジェクトです。

思想は、このケースでは、問題はあなたが、とにかく、short unsigned intとしてwchar_tを治療するためのコンパイラを言っているように、値を印刷するのに使用するものではありません。

2

標準ライブラリは、--short-wcharでコンパイルされていない可能性が最も高いです。このフラグはABIを変更しますが、名前の変更は変更されないため、これは検出されません。

+0

+1おそらくあなたは正しいでしょう。 –

0

問題は、ws[i]が間違った結果を示しているようです。生のメモリを見ると文字列には予期したデータが含まれているようです。これがなぜ起こるのかはかなりわかりません。私が見る限り、operator[]は、wchar_tへのポインタを単純に逆参照しています。これは、他の場所で正しく動作します(例:s[i])。この問題はGCCの最近のバージョン(4.6.1を試しました)とLinuxでも発生します。

代わりに*(ws.begin() + i)を使用して回避することができます。

関連する問題