C言語マクロサンプル


```C
/**
 * @file macro.h
 * @brief マクロのサンプル集.
 */
#ifndef MACRO_H
#define MACRO_H

/*
        SWAP - 変数入替 -
*/
/**
 * 2つの変数の内容を入れ替える.
 * 変数の型は引数typeで指定可能.
 * @param [in] type     入れ替え対象の変数の型
 * @param [in] a        入れ替え対象の変数1
 * @param [in] b        入れ替え対象の変数2
 * @retval なし
 * @attention 引数は複数回評価される.
 */
#define SWAP(type, a, b) \
        do {type tmp = a; a = b; b = tmp;} while (0)


/*
        XOR_SWAP - 変数入替(XOR交換) -
*/
/**
 * 2つの変数の内容をXOR交換アルゴリズムで入れ替える.
 * @param [in] a        入れ替え対象の変数1
 * @param [in] b        入れ替え対象の変数2
 * @retval なし.
 * @attention 交換対象の変数は整数(char含む)のみ可.
 * @attention 同じ変数を指定すると結果は0となる.
 * @attention 一時変数を用いて交換する方法よりも,
 * @attention 高速に動作する可能性があるため,
 * @attention 処理速度に問題がある際には検討の価値がある.
 */
#define XOR_SWAP(a, b) \
        do {a ^= b; b ^= a; a ^= b;} while (0)


/*
        MAX - 最大値取得 -
*/
/**
 * 指定された2つの引数のうち,最大のものを返す.
 * @param [in] a        最大値を選ぶ対象の変数1
 * @param [in] b        最大値を選ぶ対象の変数2
 * @retval 最大値
 * @attention 引数は複数回評価される.
 */
#define MAX(a, b) ((a) > (b) ? (a) : (b))


/*
        MAX3 - 最大値取得 -
*/
/**
 * 指定された3つの引数のうち,最大のものを返す.
 * @param [in] a        最大値を選ぶ対象の変数1
 * @param [in] b        最大値を選ぶ対象の変数2
 * @param [in] c        最大値を選ぶ対象の変数3
 * @retval 最大値
 * @attention 引数は複数回評価される.
 */
#define MAX3(a, b, c) ((a) > (MAX(b, c)) ? (a) : (MAX(b, c)))


/*
        MIN - 最小値取得 -
*/
/**
 * 指定された2つの引数のうち,最小のものを返す.
 * @param [in] a        最小値を選ぶ対象の変数1
 * @param [in] b        最小値を選ぶ対象の変数2
 * @retval 最小値
 * @attention 引数は複数回評価される.
 */
#define MIN(a, b) ((a) < (b) ? (a) : (b))


/*
        MIN3 - 最小値取得 -
*/
/**
 * 指定された3つの引数のうち,最小のものを返す.
 * @param [in] a        最小値を選ぶ対象の変数1
 * @param [in] b        最小値を選ぶ対象の変数2
 * @param [in] c        最小値を選ぶ対象の変数3
 * @retval 最小値
 * @attention 引数は複数回評価される.
 */
#define MIN3(a, b, c) ((a) < (MIN(b, c)) ? (a) : (MIN(b, c)))


/*
        IN4 - 集合要素判定 -
*/
/**
 * 指定の集合に属する要素かを判定する.
 * 判定対象xがa〜dのいずれかなら真を返却.
 * @param [in] x        判定対象
 * @param [in] a        集合要素1
 * @param [in] b        集合要素2
 * @param [in] c        集合要素3
 * @param [in] d        集合要素4
 * @retval 要素なら真.要素でなければ偽
 * @attention 引数は複数回評価される.
 */
#define IN4(x, a, b, c, d) ((x) == a || (x) == b || (x) == c || (x) == d)


/*
        INSIDE - 範囲内判定 -
*/
/**
 * 指定の範囲内かを判定する.
 * 判定対象xがa〜bの範囲内なら真を返却.
 * @param [in] x        判定対象
 * @param [in] a        範囲(小)
 * @param [in] b        範囲(大)
 * @retval 範囲内なら真.範囲外なら偽
 * @attention 範囲の引数はa<=bであること.
 * @attention 引数は複数回評価される.
 */
#define INSIDE(x, a, b) ((x) >= a && (x) <= b)


/*
        INCREMENT - インクリメント -
*/
/**
 * 引数に1を足す.その際,指定の最大値になったら0に戻す.
 * @param [in] a        インクリメント対象の変数
 * @param [in] max      最大値
 * @retval 1足された数
 * @attention 返却値はmaxにはならない.
 * @attention 1足した後の値がmaxなら0が返却される.
 */
#define INCREMENT(a, max) ((a) = ((a) + 1) % (max))


/*
        DECREMENT - デクリメント -
*/
/**
 * 引数から1を引く.0以下が渡された場合は,指定の最大値を返す.
 * @param [in] a        デクリメント対象の変数
 * @param [in] max      最大値
 * @retval 1引かれた数
 * @attention 返却値はmax未満.
 * @attention 1引いた後の値が負ならmax-1を返却.
 */
#define DECREMENT(a, max)       \
        (((a) = (a) - 1) < 0 ? ((a) = (max) - 1) : (a))


/*
        PRINT_VARIABLE - 変数内容出力 -
*/
/**
 * 変数名とその内容を指定のフォーマットで出力する.
 * @param [in] a        出力対象の変数
 * @param [in] f        フォーマット文字列
 * @retval 出力した文字数。エラー発生の場合は負数
 */
#define PRINT_VARIABLE(a, f) printf(#a " : " f "\n", a)


/*
        ELEMENT_NUM - 配列要素数取得 -
*/
/**
 * 配列の要素数を取得する.
 * @param [in] array    配列名
 * @retval 配列の要素数
 * @attention 引数にポインタは指定不可.
 */
#define ELEMENT_NUM(array) (sizeof(array) / sizeof((array)[0]))


/*
        MEMBER_SIZE - 構造体メンバサイズ取得 -
*/
/**
 * 指定された構造体のメンバのサイズを返す.
 * @param [in] type             構造体
 * @param [in] member   構造体のメンバ
 * @retval 指定された構造体のメンバのサイズ
 */
#define MEMBER_SIZE(type, member) (sizeof(((type*)0)->member))


/*
        BEEP - 警告音 -
*/
/**
 * 警告音を鳴らす.
 * @param なし
 * @retval 出力文字数.失敗の場合EOF
 */
#define BEEP() (fputc('\a', stderr))


/*
        CALC_CLOCK - 処理時間表示 -
*/
/**
 * 処理にかかったプロセッサ時間を出力する.
 * 引数にはソースコードとループ回数を指定する.
 * 使用例:CALC_CLOCK(a = sin(a), 1000000UL);
 * @param [in] code     ソースコード
 * @param [in] n        ループ回数
 * @retval なし
 */
#define CALC_CLOCK(code, n) do {        \
        int i;                                                  \
        clock_t t = clock();                    \
        for (i=0;i<(n);i++) { code; }   \
        printf("%d\n", clock() - t);    \
} while (0)


/**
 * 静的アサートで使用するテンポラリのマクロ1.
 */
#define STATIC_ASSERT_JOIN(x, y) STATIC_ASSERT_JOIN_AGAIN(x, y)


/**
 * 静的アサートで使用するテンポラリのマクロ2.
 */
#define STATIC_ASSERT_JOIN_AGAIN(x, y) x ## y


/*
        STATIC_ASSERT - 静的アサート1 -
*/
/**
 * 与えられた定数式が偽ならば,コンパイルエラーを発生させる.
 * 与えられた式が偽ならば,配列を要素数が負でtypedef,
 * コンパイルエラーを発生させることにより静的アサートを実現する.
 * 識別子に行数を加えているのは,複数のtypedefを可能にするため.
 * @param [in] e        判定対象の定数式
 * @retval なし
 */
#define STATIC_ASSERT(e) \
        typedef char STATIC_ASSERT_JOIN(ASSERTION_AT_LINE_, __LINE__) [(e) ? 1 : -1]


/*
        STATIC_ASSERT_2 - 静的アサート2 -
*/
/**
 * 与えられた定数式が偽ならば,コンパイルエラーを発生させる.
 * 関数のextern宣言を利用しての静的アサート.
 * @param [in] e        判定対象の定数式.
 * @retval なし.
 */
#define STATIC_ASSERT_2(e) \
        extern void STATIC_ASSERT_DUMMY_FUNCTION(int ASSERTION_FAILED[(e) ? 1 : -1])


/*
        STATIC_ASSERT_3 - 静的アサート3 -
*/
/**
 * 与えられた定数式が偽ならば,コンパイルエラーを発生させる.
 * enumを利用しての静的アサート.
 * @param [in] e        判定対象の定数式.
 * @retval なし.
 */
#define STATIC_ASSERT_3(e) \
        enum { STATIC_ASSERT_JOIN(ASSERTION_AT_LINE_,__LINE__) \
                = sizeof(struct { char STATIC_ASSERT_JOIN(ASSERTION_AT_LINE_,__LINE__) [(e) ? 1 : -1]; }) }


/*
        UNUSED_PARAMETER - 未使用引数の警告回避 -
*/
/**
 * 未使用の仮引数に対するワーニングを回避する.
 * @param [in] p        未使用の仮引数.
 * @retval なし.
 */
#define UNUSED_PARAMETER(p) ((void)(p))


/*
 *      ALIGN_64 - 64アライメント -
 */
/**
 * 指定された値を64毎にアライメントして返す.
 * @param [in] n        アライメント対象の数.
 * @retval      アライメントされた値.
 * @attention   63を加え、63のビット反転値で論理積をとることによりアライメントする.
 *                              この方式はアライメントの単位が2の累乗数であれば使用可能.
 *                              例えば32単位でアライメントするなら31を加え、31のビット反転値で論理積をとる.
 */
#define ALIGN_64(n) (((n) + 63U) & ~63U)


/*
 *      ALIGN_N - 汎用アライメント -
 */
/**
 * 指定された値をアライメントして返す.
 * @param [in] n        アライメント対象の数.
 * @param [in] a        アライメント単位.
 * @retval      アライメントされた値.
 * @attention   アライメントの単位が2の累乗数でない場合に使用する.
 */
#define ALIGN_N(n, a) (((n) % (a)) ? ((n) + ((a) - (n) % (a))) : (n))


#endif /* MACRO_H */
```

[C言語マクロサンプル][http://www.c-lang.org/detail/macro_sample.html]