2011-01-19 4 views
1

私のプログラムでエラーメッセージ/警告を出力する機能を、ファイル&の行番号と共に書きたいと思います。 Cにおけるこれら二つのマクロがあります。デバッグ出力機能をクリーンアップしますか?

__FILE__ 
__LINE__ 

は、私の意見では問題があります...私はこのような機能を書いているとき:

#include <stdio.h> 
#define STRINGIFY(x) #x 
#define TOSTRING(x) STRINGIFY(x) 
#define AT __FILE__ ":" TOSTRING(__LINE__) 
void error(const char *location, const char *msg) 
{ 
#ifdef DEBUG 
    printf("Error at %s: %s\n", location, msg); 
#endif 
} 
int main(int , char**) 
{ 
    error(AT, "fake error"); 
    return 0; 
} 

がたくさん残っていますリリースビルドのためにDEBUGを定義しなくても、役に立たない関数は&ゴミ箱(すべての呼び出しで__FILE____LINE__の値)をバイナリファイルに呼び出します。 これをよりうまく実現するにはどうすればよいですか? - そのようなタスクのためにあまりにも巨大になり

#include <stdio.h> 
#define STRINGIFY(x) #x 
#define TOSTRING(x) STRINGIFY(x) 
#define AT __FILE__ ":" TOSTRING(__LINE__) 
void error(const char *location, const char *msg) 
{ 
    printf("Error at %s: %s\n", location, msg); 
} 
int main(int , char**) 
{ 
#ifdef DEBUG 
    error(AT, "fake error"); 
#endif 
    return 0; 
} 

しかし、すべての関数呼び出しの前と後#ifdef DEBUG#endifを書いていない:私はこのような何かをしたいです。すべてのerror(AT, "fake error");を手動で削除すると、実際にはエレガントではありません...

アイデア?多分インライン関数(助けにならない、そうでないだろう)?いくつかのマクロまたはこの構造の変更?

答えて

2

の提案から変更eprintfが実際に行くための正しい方法である - 私はそうのようにそれを記述します

#ifdef DEBUG 
static void error(const char *file, long line, const char *msg) 
{ 
    fprintf(stderr, "Error (%s:%ld): %s\n", file, line, msg); 
} 
#define error(msg) (error)(__FILE__, __LINE__, msg) 
#else 
#define error(msg) ((void)0) 
#endif 
3

ただ、マクロにerrorを回す:

#ifdef DEBUG 
# define ERROR(l, m) error(l, m) 
#else 
# define ERROR(l, m) 
#endif 

は、その後、あなたの関数で、もちろん

ERROR(AT, "fake error"); 

書き、あなたもERRORを簡素化でき、最初のパラメータとしてATを取り除きます、この情報をマクロ定義に直接指定します。

#ifdef DEBUG 
#define error(a,b) printf("Error at %s: %s\n", (a), (b)) 
#else 
#define error(a,b) 
#endif 

また、あなたはこの可変引数マクロを使用することができ、それを毎回

1
#ifdef DEBUG 
#define ERROR(msg) error(AT, msg) 
#else 
#define ERROR(msg) 
#endif 

int main(int argc, char * argv[]) 
{ 
    ERROR("fake error"); 
    return 0; 
} 
1

何かのように#defineでエラーを置き換えますprintfは、ファイルと行番号を必要な出力とともに書き出します。

#define eprintf(...) do {fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);\ 
fprintf(stderr, __VA_ARGS__);} while(0) 

編集:マクロでerror()ラッピングjcsalomon

2

を渡すのではなく、エラーにAT動くことができる:

+0

これがためのものですC99またはC++ 0xのみであり、 '#define eprintf(...)do {fprintf(stderr、"%s:%d: "、__FILE__、__LINE__); fprintf(stderr、__VA_ARGS__)} while(0) ';余分な引数なしで生の文字列を渡せる 'fprintf(stderr、__VA_ARGS __)'の 'do {...} while(0)'と(より重要な点)で囲まれた文に注意してください。 –

+0

ya私は知っている、なぜ私はそれが上記のステートメントに似ている書いた。 – Rozuur

+0

ちょうど試してみましたが、 '__VA_ARGS __)の後に'; 'がありませんでした。そうでなければ本当に素晴らしい解決策です! – lfxgroove

関連する問題