web-dev-qa-db-ja.com

char *とunsigned char *の間でstatic_castできないのはなぜですか?

どうやら、コンパイラはそれらを無関係な型と見なし、したがってreinterpret_cast 必要とされている。なぜこれがルールですか?

40
Nick

これらは完全に異なるタイプであり、標準を参照してください。

3.9.1基本タイプ[basic.fundamental]

1文字charとして宣言されたオブジェクトは、実装の基本文字セットのメンバーを格納するのに十分な大きさでなければなりません。このセットの文字が文字オブジェクトに格納されている場合、その文字オブジェクトの整数値は、その文字の単一文字リテラル形式の値と等しくなります。 charオブジェクトが負の値を保持できるかどうかは実装定義です。文字は明示的に符号なしまたは
署名済み。 プレーン文字、符号付き文字、および符号なし文字は、3つの異なるタイプです。文字、符号付き文字、およびunsigned charは同じ量のストレージを占有し、同じアライメント要件を持ちます(basic.types);つまり、それらは同じオブジェクト表現を持ちます。文字タイプの場合、オブジェクトのすべてのビット
表現は価値表現に参加します。符号なし文字タイプの場合、値表現のすべての可能なビットパターンは数字を表します。これらの要件は、他のタイプには当てはまりません。特定の実装では、プレーンなcharオブジェクトは、signed charまたはunsigned charと同じ値を取ることができます。どちらが実装定義です。

これに類似しているのは、以下が失敗する理由でもあります。

unsigned int* a = new unsigned int(10);
int* b = static_cast<int*>(a); // error different types

abは完全に異なるタイプです。実際に質問しているのは、なぜstatic_castが以下を問題なく実行できるのか制限している理由です

unsigned int a = new unsigned int(10);
int b = static_cast<int>(a); // OK but may result in loss of precision

そして、なぜターゲットタイプが同じビットフィールド幅であり、表現できると推定できないのですか?ターゲットをソースから派生させ、ダウンキャストを実行する場合を除き、ポインターに対してはスカラー型に対してこれを行うことができますが、ポインター間のキャストは機能しません。

Bjarne Stroustropは、このリンクでstatic_castが役立つ理由を述べています: http://www.stroustrup.com/bs_faq2.html#static-cast ですが、省略形ではstatic_castは異なるポインタータイプ間のキャストをサポートしていないため、コンパイラーはこのエラーをキャッチして警告を発することができるため、ユーザーは意図を明確に述べ、意図するものが達成できることをコンパイラーに確認する機会を与えますユーザーが本当にこの変換を行いたい場合は、reinterpret_castを使用する必要があります。

30
EdChum