ifdefとかのマクロ
iOSアプリを開発している人にはおなじみであろうマクロ
#ifdef DEBUG
// do something
#endif
Xcodeでプロジェクトを作成するとDebugビルドにはDEBUG
がPreprocessor Macros
の初期値として設定されているので使用している人は多いと思う。
この#ifdef
とかに混ざって#if
も使われていたりしてマクロがカオスになっているソースがたまにある。
ということで検証
// フラグ作成
#define TEST_FLG 1
// ifdefの場合
#ifdef TEST_FLG
NSLog(@"ifdef TEST_FLG Success");
#else
NSLog(@"ifdef TEST_FLG Failure");
#endif // TEST_FLG
// ifの場合
#if TEST_FLG
NSLog(@"if TEST_FLG Success");
#else
NSLog(@"if TEST_FLG Failure");
#endif // TEST_FLG
// definedを使用する場合
#if defined(TEST_FLG)
NSLog(@"if defined(TEST_FLG) Success");
#else
NSLog(@"if defined(TEST_FLG) Failure");
#endif // TEST_FLG
#define TEST_FLG 1
の結果
全部True
ifdef TEST_FLG Success
if TEST_FLG Success
if defined(TEST_FLG) Success
#define TEST_FLG 0
の結果
ifだけFailure
ifdef TEST_FLG Success
if TEST_FLG Failure
if defined(TEST_FLG) Success
#define TEST_FLG
の結果
#if TEST_FLG
の部分でビルドエラー。
他の2つは問題無し。
#define TEST_FLG -1
の結果
#define TEST_FLG 1
と同じ結果。
ifdef TEST_FLG Success
if TEST_FLG Success
if defined(TEST_FLG) Success
ちなみに、最初に書いた
Preprocessor Macros
の初期値
というのはDEBUG=1
とされているので3つ目の結果になることはない。
あと、結果だけを見ると#ifdef
と#if defined()
は同じだけど、後者は#if defined(DEBUG) || defined(AdHoc)
みたいに条件つけられるので、個人的には好きですが結局は好みです。#ifdef
をネストさせた方がわかりやすいかもしれないし。
こんな感じで、例えばデバッグビルドとアドホックビルドのときはログ出力する、とかやっておけばいいかな、とか思っている。
#if defined(DEBUG) || defined(AdHoc)
#define LOG_DEBUG 1
#endif
#if defined(LOG_DEBUG)
#define LOG(...) NSLog(__VA_ARGS__)
#define LOGF() NSLog(@"%s:%d:", __PRETTY_FUNCTION__, __LINE__)
#else
#define LOG(...) ;
#define LOGF() ;
#endif // LOG_DEBUG
他人数で書くときはdefineとかPreprocessor Macro書くときは値は必須、とか前提を作ってから
あとはアプリとして値で分岐させるか有無で分岐させるか決めちゃえばいいと思う。
意思統率の難しそうなところだけど。