warning: left-hand operand of comma expression has no effect
警告:コンマ演算子の左側無意味
[-Wunused-value]
■1.#ifdefだらけを避けたい
#include <stdio.h>
int debug = 0 ;
void f(void)
{
#ifdef DEBUG
print("%d\n",debug);
#endif
//処理色々
#ifdef DEBUG
print("%d\n",debug);
#endif
//処理色々
#ifdef DEBUG
print("%d\n",debug);
#endif
}
DEBUG文で
#ifdefだらけ
条件コンパイルだらけにすると
コードが読み読みづらいです。
DEBUG文は地味にしましょう。
■2.警告が出てしまう非推奨修正案
#include <stdio.h>
int debug = 0 ;
//警告の出るデバッグ文
#ifdef DEBUG
#define DEBUG_print printf
#else
#define DEBUG_print
#endif
void f(void)
{
DEBUG_print("%d\n",debug); //マクロ展開後引数が残留するので警告が出る
}
上記のコードは デバッグ用に
gcc -DDEBUG でコンパイルすると
警告はでません。
しかし製品出荷用に
gcc -Dオプション無しでコンパイルすると
DEBUG_print(“%d\n”,debug) の行は
(“%d\n”,debug) とマクロ展開され
何もしないコンマ演算子だけが残ります。
関数引数のコンマはコンマ演算子ではないのですが、
マクロ展開により DEBUG_print が消えてしまうと
(“%d\n”,debug) は関数引数ではなくてコンマ演算子となります。
このコンマ演算子はコンパイルエラーにはならないのですが、
何もしないので警告が発生します。
■3.(…)を使う推奨修正案
#include <stdio.h>
int debug = 0 ;
//可変引数マクロを使用して警告が出ないように修正したデバッグ文
#ifdef DEBUG
#define DEBUG_print printf
#else
#define DEBUG_print(...) /*空*/
#endif
void f(void)
{
DEBUG_print("%d\n",debug);//マクロ展開後引数も 空 になる
}
この警告の修正方法はC99以前は面倒だったのですが、C99で導入された可変引数マクロ(…)を使うと簡単に修正できます。
出荷用にDEBUG文を無効にしたい場合
#define DEBUG_print
ではなくて
#define DEBUG_print(…) /*空*/
と可変引数マクロを使用して定義すると
マクロ展開時引数も消えるので
コンパイル時の警告も出なくなります。
/*空*/ は書かなくても良いのですが書いた方がDEBUG_print()が
/*空*/ に置き換わると理解しやすいと思います。
■4.アンケート