ifdefとかのマクロ

iOSアプリを開発している人にはおなじみであろうマクロ

#ifdef DEBUG
	// do something
#endif

Xcodeでプロジェクトを作成するとDebugビルドにはDEBUGPreprocessor 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書くときは値は必須、とか前提を作ってから
あとはアプリとして値で分岐させるか有無で分岐させるか決めちゃえばいいと思う。
意思統率の難しそうなところだけど。