1

OVS のソース コードを見ていると、今まで見たことのない非常に奇妙なコードが見つかりました。

https://github.com/openvswitch/ovs/blob/master/lib/ovs-rcu.h

void ovsrcu_postpone__(void (*function)(void *aux), void *aux);
#define ovsrcu_postpone(FUNCTION, ARG)                          \
    ((void) sizeof((FUNCTION)(ARG), 1),                         \
     (void) sizeof(*(ARG)),                                     \
     ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG))

多引数 sizeof の意味は検索でわかりました

2 つの引数で sizeof 演算子を呼び出すのはなぜですか? http://www.vxdev.com/docs/vx55man/diab5.0ppc/c-additi.htm#3001432

FUNCTION の戻り値が int で、ARG の型が char の場合、マクロはこの形式になります。

((void) 4, (void) 1, ovsrcu_postpone__((void (*)(void *))(function), arg))

ovsrcu_postpone__ メソッドの前の 2 つの引数の役割をキャッチできません。

4

2 に答える 2

3

それでは、ソースコードで提供されている例を見てみましょう。

ovsrcu_postpone(free, ovsrcu_get_protected(struct flow *, &flowp));

これは次のように展開されます。

(
 (void) sizeof((free)(ovsrcu_get_protected(struct flow *, &flowp)), 1),
 (void) sizeof(*(ovsrcu_get_protected(struct flow *, &flowp))),
 ovsrcu_postpone__((void (*)(void *))(free), ovsrcu_get_protected(struct flow *, &flowp))
)

ここにあるのは、型の安全性と、予想される呼び出しです。要件から引き出すことができるものは次のとおりです。

  • 最初の引数は、1 つの引数を持つ関数です。
  • 2 番目の引数には、少なくとも 1 レベルの間接参照 (ポインター) があります。

これも理解できます:

 sizeof(free, 1);

これはコンマ演算子を使用しているため、構文が有効であることを確認する以外は、 と同じ戻り値になりsizeof(1)ます。

于 2015-03-19T13:18:09.420 に答える
1

マクロ定義から:

void ovsrcu_postpone__(void (*function)(void *aux), void *aux);
#define ovsrcu_postpone(FUNCTION, ARG)                          \
    ((void) sizeof((FUNCTION)(ARG), 1),                         \
     (void) sizeof(*(ARG)),                                     \
     ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG))

ovsrcu_postpone(FUNCTION, ARG)これは、括弧で囲まれた 3 つのカンマ区切りの式に展開されると推測できます。

    ((void) sizeof((FUNCTION)(ARG), 1),                         \ 1
     (void) sizeof(*(ARG)),                                     \ 2
     ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG))      \ 3

Coma 演算子は、式を左から右に評価します。したがって、このコードは評価され(void) sizeof((FUNCTION)(ARG), 1)(void) sizeof(*(ARG))を呼び出しますovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG)。これは安全確認の一種です。

于 2015-03-19T13:32:07.400 に答える