1. ホーム
  2. c++

整数<->ポインタのキャストは、実際にはいつが正しいのでしょうか?

2023-11-01 22:16:05

質問

一般的な言い伝えでは、次のようになります。

  • 型システムは理由のために存在します。整数とポインタは異なる型であり、その間のキャストはほとんどの場合不正行為であり、設計ミスを示す可能性があり、避けるべきものです。

  • そのようなキャストを行う場合でも、整数とポインタのサイズについて仮定してはならない(キャスト void*int は、x64でコードが失敗する最も簡単な方法です)、代わりに int を使うべきでしょう。 intptr_t または uintptr_t から stdint.h .

知っていること 実際に役立つのはいつなのか を実行する必要があるのでしょうか?

(注意: 移植性の代償として少し短いコードを持つことは、"実際に役に立つ" としてカウントされません)。


私が知っているケースを一つ。

  • いくつかの ロックフリーのマルチプロセッサ・アルゴリズム は、2 バイト以上割り当てられたポインタがいくらかの冗長性を持っているという事実を利用しています。そして、例えばポインタの最下位ビットをブール値フラグとして使用します。適切な命令セットを持つプロセッサでは、ロック機構が不要になるかもしれません (ポインタとブーリアンフラグが別々であれば必要です)。

    (注意: この方法は、java.util.concurrent.atomic.AtomicMarkableReference によって Java で安全に行うことも可能です)。

他に何かありますか?

どのように解決するのですか?

ポインタがハッシュサムの一部である必要があるとき、ポインタを整数にキャストすることがあります。また、ポインターが常に 1 つまたは 2 つの予備のビットを持つことが保証されている特定の実装では、ポインターを整数にキャストしてビット操作を行っています。しかし、これはすべて実装に依存するので、一般的な解決策とは考えない方がいいと思います。また、ハザードポインタはこのようなもので実装できる場合があるそうです。

状況によっては、私はオブジェクトごとにユニークな ID を必要とします。これは、私のリクエスト ID として、たとえばサーバーに渡します。私がいくらかのメモリを節約する必要があり、それが価値がある場合、コンテキストによっては、私はそのような ID としてオブジェクトのアドレスを使用し、通常はそれを整数にキャストする必要があります。

組み込みシステム (例えば canon のカメラなど、chdk を参照) で作業する場合、しばしば魔法のアドレスが存在するので、そのような場合は (void*)0xFFBC5235 などがよく見られます。

を編集してください。

ただ、(心の中で)つまずいたのは pthread_self() これは通常符号なし整数への typedef である pthread_t を返します。しかし、内部的には、それは問題のスレッドを表すスレッド構造体へのポインタです。一般的に、それは不透明なハンドルのために他の場所で使用されるかもしれません。