エラーメッセージをキャッチして出力するコードをインストルメント化しようとしています。現在、私はこのようなマクロを使用しています:
_#define my_function(x) \
switch(function(x)) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
}
_
通常、関数の出力をキャプチャすることはありません。これは正常に機能します。しかし、function()
の戻り値も必要とするケースをいくつか見つけました。次のようなことを試しましたが、構文エラーになります。
_#define my_function(x) \
do { \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
} while(0)
_
関数の戻り値を保持するグローバル変数を宣言することもできますが、見栄えが悪く、プログラムがマルチスレッド化されているため、問題が発生する可能性があります。より良い解決策があることを願っています。
これは比較的複雑なコードであり、マクロで使用する理由はあまりありません。本当にヘッダーファイルに配置する場合は、inline
(C99)またはstatic
(C89)またはその両方にします。妥当なコンパイラがあれば、マクロと同じ効率になります。
GCCには ステートメント式 と呼ばれる機能があります
したがって、次のようなマクロを定義すると
#define FOO(A) ({int retval; retval = do_something(A); retval;})
それからあなたはそれを次のように使うことができます
foo = FOO(bar);
非常に遅い返事。しかし、それでもなお。インライン関数の方が優れていることに同意しますが、MACROは、インライン関数では得られないかなりの印刷の楽しみを提供します。 @qrdlに同意します。ステートメントを少し再構成すれば、ステートメント式を実際に使用できます。これがマクロでどのように機能するかです-
#define my_function(x, y) ({ \
int __err = 0; \
do { \
__err = function(x, y); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
} while(0); \
__err; \
})
これは編集です...
そのようです:
#define my_function(x, out) \
{ \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
(*(out)) = _err; \
}
参照渡しのCパラダイムを保持するには、次のようにmy_functionを呼び出す必要があります。
int output_err;
my_function(num, &output_err);
このように、後でmy_functionを実際の関数にする場合は、呼び出し参照を変更する必要はありません。
ところで、qrdlの「ステートメント式」もそれを行う良い方法です。