4

Microsoft VC2005 および g++ コンパイラの両方で、次の結果はエラーになります。

win32 VC2005 の場合: sizeof(wchar_t) は 2 です

wchar_t *foo = 0;
static_cast<unsigned short *>(foo);

結果は

error C2440: 'static_cast' : cannot convert from 'wchar_t *' to 'unsigned short *' ...

Mac OS X または Linux g++ の場合: sizeof(wchar_t) は 4

wchar_t *foo = 0;
static_cast<unsigned int *>(foo);

結果は

error: invalid static_cast from type 'wchar_t*' to type 'unsigned int*'

もちろん、いつでもreinterpret_castを使用できます。ただし、適切な整数型に static_cast することがコンパイラによって違法と見なされる理由を理解したいと思います。きっとちゃんとした理由があるのに…

4

4 に答える 4

6

関連のないポインター型間でキャストすることはできません。指している型のサイズは関係ありません。型のアラインメント要件が異なる場合を考えてみましょう。このようなキャストを許可すると、一部のプロセッサで不正なコードが生成される可能性があります。異なる型へのポインタが異なるサイズを持つことも可能です。これにより、取得したポインターが無効になったり、まったく別の場所を指したりする可能性があります。Reinterpret_cast は、プログラムのコンパイラ アーキテクチャと OS を知っていれば、回避できるエスケープ ハッチの 1 つです。

于 2009-08-06T13:02:14.587 に答える
4

と同様にchar、 の符号性wchar_tは標準では定義されていません。これを 2 以外の補数の整数の可能性と合わせて、 for a wchar_tvalue c

*reinterpret_cast<unsigned short *>(&c)

等しくない可能性があります:

static_cast<unsigned short>(c)

wchar_t2 番目のケースでは、 が符号 + 大きさまたは 1 の補数型である実装では、c の負の値はモジュロ 2^N を使用して符号なしに変換され、ビットが変更されます。前者の場合、ビット パターンが取得され、そのまま使用されます (まったく機能する場合)。

ここで、結果が異なる場合、実装がstatic_castポインター型の間に を提供する現実的な方法はありません。unsigned short*「ちなみに、これからロードするときは、符号変換も行う必要があります」と言って、ポインターにフラグを設定し、すべての符号なしの短いロードでこのフラグをチェックするにはどうすればよいでしょうか?

そのため、一般に、異なる整数型へのポインター間でキャストすることは安全ではありません。この安全性の欠如が、それらの間で static_cast を介した変換がない理由であると私は信じています。

キャスト先の型がたまたま wchar_t のいわゆる「基になる型」​​である場合、結果のコードはほぼ確実に実装には問題ありませんが、移植性はありません。したがって、標準では、おそらく移植可能なコードのエラーを隠すため、そのタイプだけに static_cast を許可する特別なケースは提供していません。reinterpret_cast が安全であることがわかっている場合は、そのまま使用できます。確かに、コンパイル時に安全であることをアサートする簡単な方法があると便利ですが、標準に関する限り、reinterpret_castクラッシュせずに ed ポインターを逆参照する必要さえない実装であるため、それを回避するように設計する必要があります。

于 2009-08-06T13:14:28.740 に答える
2

ナロー可能な型によって制限された static_cast の仕様による使用 (例: std::ostream& から std::ofstream& へ)。実際、wchar_t は単なる拡張機能ですが、広く使用されています。あなたのケース(本当に必要な場合)は reinterpret_cast で修正する必要があります

ところで、MSVC++ にはオプションがあります - wchar_t をマクロ (ショート) またはスタンドアロンのデータ型として扱います。

于 2009-08-06T12:47:11.737 に答える
1

ポインターは魔法の「制限なし、何でもあり」ツールではありません。

それらは、言語仕様により、実際には非常に制限されています。型システムや残りの C++ 言語をバイパスすることはできません。これは、あなたがしようとしていることです。

コンパイラに、「wchar_t以前にこのアドレスに保存したものが実際には int であるふりをするように指示しようとしています。今それを読んでください。」

それは意味がありません。そのアドレスに格納されているオブジェクトは でありwchar_t、それ以外には何もありません。あなたは静的に型付けされた言語で作業しています。つまり、すべてのオブジェクトが 1 つの型を持ち、1 つの型を突き出します。

実装で定義された動作の世界に迷い込みたい場合は、 reinterpret_cast を使用して、コンパイラに問題がないふりをして、適切と思われる結果を解釈するように指示できます。ただし、結果は標準ではなく、実装によって指定されます。

そのキャストがなければ、操作は無意味です。Awchar_tintまたは ではありませんshort

于 2009-08-06T15:21:27.450 に答える