TOP >> マニアックなプログラミング
トリッキーコードネット トリッキーなコード

【トリッキーなコード】デバッグ用printfマクロ (C言語)

C言語の前処理(pre-process)は、コンパイラ言語の特徴を活用した、とても便利な機能だと思います。

例えば、デバック時と本番運用時で、関数の中身やコードを書き換えたい場合などは、以下のようにします。
#define DEBUG #ifdef DEBUG ~~ デバッグ用コード ~~ #else ~~ 本番用コード ~~ #endif
こうしておくことで、#define DEBUG を コメントアウト or コメントアウトを外すだけで、 本番用コードとデバッグ用コードを切り替えることができます。 ・・・って、はい、常識ですね♪ しかし、しかし、 プログラミングにデバッグ作業はつきもので、 デバッグ作業には、デバッグ用のコードが必要で、 デバッグ用コードと本番用コードを切り替える為に、 あちらこちらに #ifdef, #else, #endif を書きまくるのは、 何だかソースコードが汚らしく見えてしまい、非常にナンセンス ヽ(`Д´#)ノ ムキー!! ※ 余談ですが、スクリプト言語にはもちろん前処理機能がない為、コードを切り分けるには、 「コード中のif-elseで切り分ける」か、「あちらこちらにコメントアウトして回る」しか、方法がありません。 コメントアウトに関しても、(コンパイラ言語の様に)実行時に取り除かれるワケではない為、 その分 余計な負荷がマシンに掛からないか、とっても心配になります(← 小心者w)。 え~っと、前置きが長くなりましたが、 ここでとっておきのデバッグ用printfマクロをご紹介します。
#define DEBUG #ifdef DEBUG #define debug_printf printf #else #define debug_printf 1 ? (void) 0 : printf #endif

Cコード例)

#include <stdio.h> #define DEBUG #ifdef DEBUG #define debug_printf printf #else #define debug_printf 1 ? (void) 0 : printf #endif int main(void) { int i = 3; debug_printf("%d", 3); return 0; }
結果は、 DEBUGが定義されていたら、3が表示 DEBUGが定義されていたら、何も表示されません。 補足しておくと、DEBUGが定義されていないと、 debug_printf("%d", 3); ← の部分は 1 ? (void) 0 : printf("%d", 3); ← となります。 この時、絶対に実行されない printf("%d", 3); のコードは、 コンパイラの最適化機能により、コンパイル後の実行ファイルからは跡形もなく消え去っている! というわけです^^;) 冒頭の、「#ifdef-#else-#endif を使ってコードを切り分ける」王道の方法よりも、 幾分スマートにコードを切り分けられるのではないでしょうか?? ついでにおまけ:

任意の関数の有効/無効の切り替えマクロ

printfだけではなく、任意の関数の有効/無効を切り替えれるマクロの例です。
#ifdef DEBUG #define debug #else #define debug 1 ? (void)0 : #endif
使用例) debug hogehoge_func(); これも(・∀・)イイ! 早速使ってみようと思います~~。
トリッキーコードネット の TOPへ HOTNEWS の 総合TOPへ