2

これは Linux カーネル ソースからの抜粋です。stem##使用法は何ですか?cで初めて見た

#define __pcpu_size_call_return(stem, variable)                         \
({      typeof(variable) pscr_ret__;                                    \
    __verify_pcpu_ptr(&(variable));                                 \
    switch(sizeof(variable)) {                                      \
    case 1: pscr_ret__ = stem##1(variable);break;                   \
    case 2: pscr_ret__ = stem##2(variable);break;                   \
    case 4: pscr_ret__ = stem##4(variable);break;                   \
    case 8: pscr_ret__ = stem##8(variable);break;                   \
    default:                                                        \
            __bad_size_call_parameter();break;                      \
    }                                                               \
    pscr_ret__;                                                     \
 })
4

2 に答える 2

9

プリプロセッサ演算子##は、マクロ展開中に実引数を連結する方法を提供します。置換テキストのパラメーターが に隣接している##場合、パラメーターは実際の引数に置き換えられ、## と周囲の空白が削除され、結果が再スキャンされます。たとえば、マクロ paste は 2 つの引数を連結します。

#define paste(front, back) front ## back

paste(name, 1)トークンを作成しますname1

于 2013-06-12T05:48:07.867 に答える
6

演算子は、トークンを結合して単一##のトークンを形成するプリプロセッサ操作です。

したがって、共通のプレフィックスに基づいて 2 つの関数を呼び出し、毎回 1 つの引数を渡し、それを変更できるようにしたいとします。

以下は使用できません。

#define CallBoth(pref,arg) \
{ \
    arg = pref A (arg); \
    arg = pref B (arg); \
}

置換されたprefand A(またはB) は別個のトークンになるためです。同様に、次のものは使用できません。

#define CallBoth(pref,arg) \
{ \
    arg = prefA (arg); \
    arg = prefB (arg); \
}

prefAorの置換がprefB行われないためです。

これを行うには、次を使用します。

#define CallBoth(pref,arg) \
    { \
        arg = pref##A(arg); \
        arg = pref##B(arg); \
    }    

置換されたprefand A(or B) は 1 つのトークンに連結されます。そのように、次のように入力すると:

CallBoth(xyzzy,intVar);

それは次のように翻訳されます:

{
    intVar = xyzzyA(intVar);
    intVar = xyzzyB(intVar);
}

この機能がなければ、関数名を表す 1 つのトークンで終わる方法はありません。


参照しているファイルのコメントに記載されているように:

/* 関数を、処理されるオブジェクトのさまざまなスカラー サイズに対して呼び出される一連の関数に分割するための分岐関数。*/

したがって、マクロに与えられる変数のサイズに応じて、次のいずれかが呼び出されます。

stem1(variable)
stem2(variable)
stem4(variable)
stem8(variable)

ここでstem、 とvariableは、マクロへのパラメーターとして提供されます。または、これらのサイズのいずれ__bad_size_call_parameter()も関連しない場合に呼び出されます。

だから、呼び出し:

char char_var;
__pcpu_size_call_return(xyzzy,char_var)

呼び出しになります:

xyzzy1(char_var):

int int_var;
__pcpu_size_call_return(xyzzy,int_var)

呼び出しになります:

xyzzy4(int_var)

どこでsizeof(int) == 4

于 2013-06-12T05:48:44.867 に答える