プリプロセッサの文法 (マクロの文法)

## トークンの結合

#define HOGE(a) fo##a

NSString *foo = @"Hello World";
NSLog(HOGE(o));

結果: Hello World
HOGE(o)のところがfooになるので、fooという変数をNSLogに与えたNSLog(foo);と書いたことと同じになり、
Hello Worldが出力される。

... 可変引数

__VA_ARGS__ で参照可能になる。

#define HOGE(...) NSLog(__VA_ARGS__)

HOGE(@">>> %@ <<<", @"Hello World");

結果: >>> Hello World <<<

関数マクロ

すでに可変引数を説明してしまっているが、括弧を使う形で引数を受け取るマクロを定義できる。

#define MY_MAX(a, zzzz) (a) > (zzzz) ? a : zzzz

NSLog(@"%d", MY_MAX(3,99));

結果: 99

fmt, ...

引数の名前は何でもよいのだが、フォーマット的な意味でfmtという引数の名前がよく使われているように思える。

#define MY_DEBUG(fmt, ...) NSLog(@"%d行目 " fmt, __LINE__, ##__VA_ARGS__)

NSString *s = @"こんにちわ";
MY_DEBUG(@"s : %@", s);

結果: 22行目 こんにちわ

個人的には##いらないんじゃ?と思った

個人的には##__VA_ARGS__の##の部分要らない気がするのだけれど....違うのだろうか...

とおもったら

と思ったら答えが載っていました。
tez: Diary: VA_ARGS マクロ
__VA_ARGS__ が空のときのおまじないとか。

たしかに
MY_DEBUG(@"テスト");

としたとき

#define MY_DEBUG(fmt, ...) NSLog(@"%d行目 " fmt, __LINE__, __VA_ARGS__)

だとエラーになることを確認。

#defineした定数を#defineの右辺でも使いたいとき

普通に定数名を右辺に書けば展開されている

#define HELLO @"こんにちは"
#define STR   HELLO @"せかい"

NSLog(@"%@", STR);

結果: こんにちはせかい