2011-10-10 7 views
3

解決策がインターネットでかなり検索された後、私の解決策が良いかどうかここで尋ねることにしました。MACROSを使用して機能を無効にする

私はシンプルでモジュラーなCロギングライブラリを作成しようとしています。これは、簡単に無効にし、博士課程の学生や研究者がロギングシステムの影響を可能な限り減らすアルゴリズムをデバッグするのを助けます。

私の問題は、私はロガーのコストは、Cのコードは次のようになります0

である実行可能ファイルを生成するコンパイル時にロギングシステムを無効にするには、ライブラリのユーザのために可能にしたいということです:

これは単にロガーを初期化します。私はassert.hヘッダーをチェックしているが、私の場合はsoulutionの結果が警告のリストになるサンプルコードを探しています。実際、logger_init()がマクロを使って0に置き換えられた場合、変数loggerは決して使用されません。

int logger_init(logger_t *logger); 

#ifndef NLOG /* NLOG not defined -> enable logging */ 
int logger_init(logger_t *logger) { 
... 
} 
#else /* NLOG defined --> the logging system must be disabled */ 
#define logger_init(logger)  (int)((logger = NULL) == NULL) 
#endif /* NLOG */ 

これは警告にはならないと私はまた、関数を呼び出しのオーバーヘッドを避ける:私はこの方法を使用することにしました。このため

。実際には私の最初の試みはこのようにすることでした:

私はそれを必要としなくても機能を呼び出し続けます。

私の解決策は良い解決策と考えることができると思いますか?より良い解決策はありますか?

ありがとう、みんな! 乾杯、 アルマンド

+2

空の関数はジョブを実行し、コンパイラはそれらをインライン化してから削除します。 – paulm

答えて

7

そのための標準的なイディオムは、少なくとも90年代であった:

#ifndef NLOG 
void logger_init(logger_t *logger); 
void logger_log(logger_t *logger, ...); 
#else 
#define logger_init (void)sizeof 
#define logger_log (void)sizeof 
#endif 

彼らは構文チェックをしているものののsizeofのオペランドが、評価されないことに注意してください。 sizeof演算子は、いくつかのカンマ演算子とexpresionが表示されますので、このトリックは、可変引数関数でも動作します:sizeofではありません(

(void)sizeof(log, 1, 2, 3); 

これらのカンマが分離されていないパラメータ:

logger_log(log, 1, 2, 3); 

はに変換します関数ですが、演算子です)が、カンマ演算子です。

戻り値をintからvoidに変更しました。実際の必要はありませんが、sizeofの返品はほとんど意味がありません。

+0

は絶対にクリアです。私はこの解決策に固執するでしょう!ありがとうございます – Armando

+0

今すぐソリューションを試してみて、この警告を生成することが判明: "警告:オペレータsizeofに渡されるパラメータのリストのため、コンマ式の左オペランドは効果がありません[-Wunused-value]"。どのような作業arroundことができますか? – Armando

+0

何もしないコードを書くのは難しく、同時に何もしないコードについてのすべてのコンパイラの警告を避けることができます。スマートな使い方をしても、コンパイラをアップグレードするたびに警告が再び表示されます。だから私のアドバイスは '-Wno-unused-value'をコンパイラコマンドに追加することです。他のオプションは '#define logger_init(x)(void)0'を実行することですが、可変長関数を持っている場合は可変長マクロも必要です。そして、あなたは他の理由で未使用の警告を受けるかもしれません... – rodrigo

0

はあなたの無効バージョンは単に定数にすることはできません。

#ifndef NLOG /* NLOG not defined -> enable logging */ 
int logger_init(logger_t *logger) { 
... 
} 
#else /* NLOG defined --> the logging system must be disabled */ 
#define logger_init(logger)  0 
#endif /* NLOG */ 

この方法では、あなただけの持っている(プリコンパイル後):すべての警告を生成してはならないresult = 0;

+0

私が書いたように、これは変数ロガーが不要になり、コンパイラによって警告が発生します。 – Armando

+0

申し訳ありませんが、そのビットを誤って読んで...再び考えます! – asc99c

関連する問題