13
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))

これは、これら 2 つのマクロの定義です。コードの後半で、LOGIこのLOGWように使用されます

LOGI("accelerometer: x=%f y=%f z=%f",
                                event.acceleration.x, event.acceleration.y,
                                event.acceleration.z);

そしてこのように

LOGW("Unable to eglMakeCurrent");

私は複雑なマクロを避けようとしているので#define、一般的に、このマクロが実際に何を意味するのか理解できません。ここでの 3 つのドット表記の役割は何ですか? これにより、コードの後半で何が#define変更されますか?

明らかに、3つのドットが不特定の数の引数を示すために使用されていることは知っていますが、この状況の読み方がわかりません。

4

1 に答える 1

16

C99 標準では、可変個引数マクロ、つまり可変数の引数を取ることができる関数のようなマクロが導入されました。

C 標準の最新のドラフト、セクション 6.10.3 を引用します。

マクロ定義の識別子リストが省略記号で終わらない場合、関数のようなマクロの呼び出しにおける引数の数 (前処理トークンを含まない引数を含む) は、マクロ定義のパラメーターの数と等しくなければなりません。それ以外の場合、呼び出しには、マクロ定義のパラメーターよりも多くの引数が必要です ( を除く...)。呼び出しを終了する ) 前処理トークンが存在する必要があります。

識別子__VA_ARGS__は、パラメーターで省略記号表記を使用する関数のようなマクロの置換リストでのみ発生します。

...

マクロ定義の identifier-list にa がある場合...、後続の引数 (区切りのカンマ前処理トークンを含む) がマージされて、1 つの項目 (可変引数) が形成されます。このように結合された引数の数は、マージ後、引数の数がマクロ定義のパラメーターの数よりも 1 つ多くなります ( を除く...)。

そして次のサブセクションでは:

置換リストに出現する識別子__VA_ARGS__は、それがパラメーターであるかのように扱われ、可変引数は、それを置き換えるために使用される前処理トークンを形成するものとします。

LOGIしたがって、 orを必要な数の引数で呼び出すことができLOGW、それらはすべて への参照によって定義で指定された場所に展開されます__VA_ARGS__

于 2012-09-15T05:05:46.463 に答える