次のコードは、CとC++の両方でコンパイルする必要がある既存のアプリケーションのものです。マクロがあります:キャストと型チェックを行うこのハードコアマクロについて説明してください
次のように使用されている/* Type-checking macro to provide arguments for CoCreateInstance() etc.
* The pointer arithmetic is a compile-time pointer type check that 'obj'
* really is a 'type **', but is intended to have no effect at runtime. */
#define COMPTR(type, obj) &IID_##type, \
(void **)(void *)((obj) + (sizeof((obj)-(type **)(obj))) \
- (sizeof((obj)-(type **)(obj))))
:
ISomeInterface *object;
CoCreateInstance(&CLSID_SomeInterfaceImpl, NULL,
CLSCTX_INPROC_SERVER, COMPTR(ISomeInterface, &object))));
ここでの考え方は、CoCreateInstance()
の最後の2つのパラメータはIID&
とvoid**
していることで、マクログラブISomeInterface**
ものとIID&
に変換し、 void**
と同時に、ISomeInterface**
の代わりに渡されたアドレスが実際にはISomeInterface*
ポインタ変数のアドレスであることをコンパイル時検査を実施する。
わかりましたが、
((obj) + (sizeof((obj)-(type **)(obj))) \
- (sizeof((obj)-(type **)(obj)))
複雑な式の必要性は何ですか?私はタイプチェックが(obj)-(type**)(obj)
の部分式で実施されていることを知ります。 sizeof()
を追加してから差し引く必要はありますか?キャストする前にvoid*
にキャストする必要性はvoid**
になりますか?
私は次のように同じことが行うことができたとします。ここ
#define COMPTR(type, obj) &IID_##type, \
(void **)(sizeof((obj)-(type**)(obj)), obj)
コンマ演算子の最初の部分はです。TypeCheckを施行し、定数に評価されますsizeof()
を含むことになり、2番目の部分はちょうどもたらすであろう同じポインタとポインタはvoid**
にキャストされます。
私の提案したマクロは、元のマクロで何ができますか?これらの合併症の必要性は何ですか?
これが悪いコードです。私は一日中これに苦しんできたと思いますか? – orlp
@ nightcracker:いいえ、私はそのコードを維持していません。私はそれを見つけて、それがどのように機能しているのか興味がありました。 – sharptooth
タイトルのハードコアの場合は+1、タグにする必要があります! –