【C言語】
デバッグ用のprintfをリリース時無効(空)にする方法

warning: left-hand operand of comma expression has no effect

警告:コンマ演算子の左側無意味
[-Wunused-value]

■この記事の概要

C言語でのデバッグ用printfをリリース時に無効にする方法を解説。

この記事では、コンパイル時にデバッグコードを除去する手法として、可変引数マクロの活用と、警告を回避するための具体的な構文について説明しています。


■#ifdefだらけを避けたい

#include    <stdio.h>
int main(void)
{
#ifdef  DEBUG
    printf("デバッグ開始\n");
#endif
    //処理色々
#ifdef  DEBUG
    printf("%s\n",__FILE__);
#endif
    //処理色々
#ifdef  DEBUG
    printf("%s\n",__func__);
#endif
    //処理色々
#ifdef  DEBUG
    printf("%d\n",__LINE__);
#endif
}

DEBUG文で
#ifdefだらけ
条件コンパイルだらけにすると
コードが読み読みづらいです。

DEBUG文は地味にしましょう。

■コンパイル時警告が出る非推奨修正案

#include    <stdio.h>
//警告の出るデバッグ文
#ifdef  DEBUG
#define DEBUG_printf    printf
#else
#define DEBUG_printf 
#endif
int main(void)
{
    DEBUG_printf("デバッグ開始\n");
    //処理色々
    DEBUG_printf("%s\n",__FILE__);
    //処理色々
    DEBUG_printf("%s\n",__func__);
    //処理色々
    DEBUG_printf("%d\n",__LINE__);
}

上記のコードは デバッグ用に
gcc -DDEBUG でコンパイルすると
警告はでません。

しかし製品出荷用に
gcc  -Dオプション無しでコンパイルすると
DEBUG_print(“%s\n”,__FILE__) の行は
(“%s\n”,__FILE__) とマクロ展開され
何もしないコンマ演算子だけが残ります。

関数引数のコンマはコンマ演算子ではないのですが、
マクロ展開により DEBUG_print が消えてしまうと
(“%s\n”,__FILE__) は関数引数ではなくてコンマ演算子となります。


このコンマ演算子はコンパイルエラーにはならないのですが、
何もしないので警告が発生します。

■可変引数マクロ(…)を使う推奨修正案

#include    <stdio.h>
//警告の出ないデバッグ文
#ifdef  DEBUG
#define DEBUG_printf    printf
#else
#define DEBUG_printf(...)   /*空*/ 
#endif
int main(void)
{
    DEBUG_printf("デバッグ開始\n");
    //処理色々
    DEBUG_printf("%s\n",__FILE__);
    //処理色々
    DEBUG_printf("%s\n",__func__);
    //処理色々
    DEBUG_printf("%d\n",__LINE__);
}

この警告の修正方法はC99以前は面倒だったのですが、C99で導入された可変引数マクロ(…)を使うと簡単に修正できます。
出荷用にDEBUG文を無効にしたい場合 
#define  DEBUG_print
ではなくて
#define  DEBUG_print(…)   /*空*/
とか
#define  DEBUG_print(…)   /*何もしない*/

可変引数マクロを使用して定義すると
マクロ展開時引数も消えるので
コンパイル時の警告も出なくなります。
/*空*/ は書かなくても良いのですが書いた方がDEBUG_print()が
/*空*/ に置き換わると理解しやすいと思います。

■アンケート

6
DEBUG文で警告が出た時一番多い対応は?