5

コード:

char keyStr[50]={ 0x5F, 0x80 /* bla bla */ };
uint32_t* reCast  = reinterpret_cast< uint32_t* >( &keyStr[29] );
uint32_t* reCast2 = ( uint32_t* )&keyStr[29];
if( reCast == reCast2 ){
    cout << "Same Thing!";
}

出力:

同じこと!

2 つのキャスト方法の違いは何だろうか。また、(例を使用して)static_cast、dynamic_cast、および他のタイプのキャストの違いを指定できれば(つまり、できるだけ低レベルでアセンブリ言語にできるだけ近い状態で)。

static_cast
dynamic_cast
const_cast
reinterpret_cast
C-style cast (type)value
Function-style cast type(value)

ありがとう。

reinterpret_cast が int ポインターに keyStr[29] のアドレスを割り当てることを上記の例から知っている PS を読んでください。

lea eax, [keyStr+1D]
mov [reCast], eax

つまり、低レベルの見通しでは、元のデータを変更しないため、reinterpret_cast はまったく危険ではありません。

他のキャスト メソッドが低レベルでどのように動作するかを知りたかったのです。したがって、たとえば、オブジェクトは、低レベルの方法では、アドレスを保持する単なる変数です。そして、そのオブジェクトの型は、コンパイラがそのアドレスを解釈し、それをオフセットする方法です(これはまさに私が興味のないものです。アセンブリでは、その変数が値、ポインター、またはオブジェクト (つまり、別のポインター) )。まったく同じかもしれないもう 1 つのことは、int と int* または unsigned int と int の違いです。4 つの宣言はすべて同じアセンブリ命令を生成します。( push value ) または (sub esp-(length of int) && mov esp, value) これで質問が明確になり、「低レベルコード」および「アセンブリ」とタグ付けした理由が明確になることを願っています

PSこのプログラムでは、移植性やその他の高レベルのものは気にしません。私はできるだけ低レベルで、できるだけアセンブリ言語に近づけようとしています。つまり、このプログラムでは、メモリは単なるメモリ (つまり 0 と 1 ビット) であり、型は重要ではありません (たとえば、mem アドレス: 0x123 が「int」型か「float」型かは気にしません。 "データ")

4

4 に答える 4

0

あなたの例では、C スタイルのキャストと reinterpret_cast の間に違いはありません。これは、無関係なポインター間でキャストしており、constnessがないためです。1 つの部分があったconst場合、C スタイルのキャストが内部で const_cast を実行すると、reinterpret_cast が停止します。

reinterpret_cast (または C スタイルのキャスト) の危険性は、関連のないオブジェクト間のキャストを可能にすることです。あなたの例では、逆参照reCast(またはreCast2) すると、位置合わせされていない整数にアクセスしようとするため、エラーが発生するリスクが高くなります。

低レベルでは、すべてのキャストは同じ効果を持ちます (それらが有効な場合): それらはすべて値またはアドレスを提供します。主な違いは次のとおりです。

  • C スタイルのキャストは、コンパイル時に (ほぼ) 常に許可されます。コンパイル エラーが発生する例はわかりませんが、コンパイラに依存する可能性があります。
  • constness の変更がない限り、同じケースで reinterpret_cast が許可されます。
  • const_cast は constness のみを変更できます
  • static_cast は、関連する型間でのみ (コンパイル時に) 許可されます

このキャストはすべて C++ で追加され、C スタイル キャストのすべてをキャッチするモードを回避し、コンパイルおよび実行時のチェックを可能にします。- dynamic_cast は、関連する型の間でコンパイル時にのみ許可されコンパイラは実行時に有効性を制御するコードを挿入します

于 2014-12-08T15:39:21.663 に答える
0

「危険ではない」とはどういう意味ですか? reinterpret_cast は非常に危険です。これは、コンパイラが値について知っていると考えていることを無視しても安全であることをコンパイラに伝えます。

問題の値の定数/揮発性と、それが指しているものに関する情報を捨てるCスタイルのキャストほど危険ではありません。

アセンブリ言語でこれらの操作を理解することは、少し無意味です。それらはアセンブリ言語の構成要素ではありません。これらは C++ 言語構造であり、次のように機能します。

static_cast- 事実上、これはオブジェクトをあるタイプから別のタイプに変換します。これにより値が変更される可能性があることに注意してください (static_cast<float>(1)たとえば、 は 1 と同じビット パターンを持っていません)。

dynamic_cast- このオブジェクトが継承によって別のタイプであると見なすことができる場合は、そのように扱い、そうでない場合はゼロとしてレンダリングします。これはポインターの値を変更しませんが、コンパイラーのビューを安全に変更します。

const_cast-修飾子を破棄const(またはvolatile) します。これは、クライアントが安全だと考えていたデータを破棄できるため、あまり良い考えではありません。

reinterpret_cast-ビットパターンを、コンパイラが考えていたものとは異なる意味として扱います。通常はポインターに使用されますが、めったに使用されないことを願っています。reinterpret_castint を a に変換することfloatはあまり良い考えではありませんが、同じビット パターンを保持します。

c-style-cast - ビット パターンを取得し、それについて知っていることを完全に忘れて、別のものとして扱います。との危険でほとんど目に見えないstatic_cast組み合わせ。レビューで見つけるのが難しく、何が起こっているのか具体的ではないため、C++ コードでは良いアイデアとは見なされません。reinterpret_castconst_cast

于 2014-12-08T15:29:30.573 に答える
-1

違いは、C++ ファイルで C スタイルのキャストを使用すると、エラーが発生してコンパイルできない場合があることです。reinterpret_castそのような場合を解決します。コンパイラーに次のように伝えます。C++ は、キャストなどに関して C よりもはるかに制限されています。

于 2014-12-08T15:19:49.937 に答える