4

C でオブジェクト指向プログラミングを支援するマクロを作成しようとしています。クラス情報を定数構造体に格納するため、次のことを行うマクロを作成する必要があります。

  • オブジェクトの型を取る (逆参照されたポインタの型)
  • 追加_infoして、目的の classInfo 構造体の名前を取得します
  • 関数に渡すことができるように、そのシンボルのアドレスを取得します
  • destroyObjectクラス構造体とオブジェクト自体へのポインターを使用して関数を呼び出します

例:

queue_t* p = NULL;
delete(p);

delete次のように展開する必要があります。

destroyObject(&(queue_t_info), p);

このマクロを使用してみましたが、作業に取り掛かることができません:

#define delete(X) (destroyObject(&(typeof(*X)##_info), X))

typeof パーツが正しく機能しないという問題があります。

4

2 に答える 2

7

typeofマクロではなく、言語構築であり、プリプロセッサではなくコンパイラによって展開されます。前処理はコンパイルの前に行われるため、マクロはtypeof結果にアクセスできません。

展開delete(p)先: (destroyObject(&(typeof(*p)_info), p))-E( gcc フラグで確認できます)

于 2013-02-26T11:36:15.573 に答える
2

私がやろうとしていたことは不可能であることに気付きました.Cプリプロセッサはコードを解析および記号化しないため、変数の型がわかりません.

これを解決するには、タイプを削除関数にも渡す必要があります。これは、タイプの不一致によるバグの原因が頻繁に発生するため、理想的ではありません。プログラマーがオブジェクト A へのポインターを渡し、delete 関数でオブジェクト B を指定すると、間違ったデストラクタが呼び出されます。これを解決するために、型チェックをマクロに追加して、型が一致しない場合にコンパイラの警告が生成されるようにしました。

#define typecheck(type,x) \
({  type __dummy; \
typeof(x) __dummy2; \
(void)(&__dummy == &__dummy2); \
})

#define delete(P, X) (destroyObject(&(X##_info), P), typecheck(X, *P))
#define new(X, ...) (createObject(&(X##_info), ##__VA_ARGS__))

マクロの通常の使用法:

queue_t* p = new(queue_t);
delete(p, queue_t);

ただし、間違ったタイプを使用しています:

queue_t* p = new(queue_t);
delete(p, int);

コンパイラの警告が発生します:

Comparison of distinct pointer types ('int *' and 'typeof (*p) *' (aka 'queue_t *'))
于 2013-02-26T11:40:42.283 に答える