2013-10-15 8 views
6

マルチプロセッサプログラミングの技術p215では、Cではポインタからビットを「盗む」ことができ、ビット単位の演算子を使用するとフラグ(マーク)を抽出し、単一の単語からのポインタ。私はこれがどのように行われたのかわからないので、例が私を助けます。ポインタからビットを盗む

+3

本当にそうする正当な理由がない限り、これは悪い習慣が一般的であることを知っておくと便利かもしれません。 – Mysticial

+1

@Mysticial:動的言語を実装するのが一般的です。 –

+2

@Mysticial:ある単語にアトムを実行する必要があるときがあります。 –

答えて

7

ポインタサイズが32ビットのシステムを想定していますが、1GBのメモリしか使用できません。メモリ空間全体を扱うのに30ビットしか必要ないので、上位2ビットは使用されません。これらの上位2ビットは、ポインタタイプ(スタック/グローバル/ダイナミック)でポインタをマークするなど、独自の目的に使用できます。

結果として得られるコードは、移植可能なほどの移植性がないことに注意してください。あなたのコードが実行されているCPUに精通している必要があります。具体的には、ポインタからのアドレスがアドレスバスに送られたときに上位ビットがドロップされるかどうかを知る必要があります。

+2

これは、68000ベースのシステムでは、アドレス空間がわずか24ビットであるため、非常に一般的でした.32ビットアドレスの上位8ビットは、さまざまなフラグに安全に使用できました。 1980年代の元々のMac OSは、ロックされた、消去可能な、リソースフラグのためにこのトリックを使いました。 –

7
  1. すべてのポインタが偶数になるようにpointeeオブジェクトがメモリ内で整列されていることを確認します。最後のビットは、単一のブール値フラグを格納するために解放されます。

  2. ポインターをタイプuintptr_tの整数として動かしてください(これは完全に移植可能ではありません)。これらは、簡単に操作することができます。

    bool get_flag(uintptr_t p) 
    { 
        return p & 1; 
    } 
    
    void *get_pointer(uintptr_t p) 
    { 
        return (void *)(p & (UINTPTR_MAX^1)); 
    } 
    
    uintptr_t set_flag(uintptr_t p, bool value) 
    { 
        return (p & (UINTPTR_MAX^1)) | value; 
    } 
    
+0

どのようにJavaで同じを達成するのですか? – arunmoezhi

+1

JavaはNanny言語です.... Nannyはあなたにそれをさせませんでした:-P – WhiZTiM

+0

Javaでは、同じ機能(共有オブジェクトへのアクセスを同期させることを意図しています)はAtomicMarkableReference'クラスで利用できます。今日のナニーは、過去千年とは違って... –

関連する問題