2009-08-25 28 views
3

私はそのコードの下に与えられている私のアプリケーションでエラーメッセージを出力し、可変引数機能を持っている:可変引数関数をマクロに変換する方法は?

void error(char *format,...) 
{ va_list args; 
    printf("Error: "); 
    va_start(args, format); 
    vfprintf(stderr, format, args); 
    va_end(args); 
    printf("\n"); 
    abort(); 
} 

次のようにこの関数は、エラー条件で使用されます。

error("invalid image width %d and image height %d in GIF file %s",wid,hei,name); 

error()関数であります異なる引数を持つ異なる場所から呼び出されます(可変引数関数)。

関数のアプローチがうまく機能します。

ここで、この関数をマクロに変換する必要がある場合はどうすればよいですか?私はそれをやってみました:

#define error(format) {va_list args;\ 
    printf("Error: ");\ 
    va_start(args, format);\ 
    vfprintf(stderr, format, args);\ 
    va_end(args);\ 
    printf("\n"); abort()} 

しかし、これは引数を正しく出力しません。

上記のマクロ定義で何が問題になっていますか?

修正プログラムとは何ですか。

答えて

2

あなたのコンパイラはISOスタイル可変引数マクロをサポートしている場合は、あなたのようなマクロを定義することができます。

:あなたはGCCを使用している場合

#define error(...) \  
    fprintf(stderr, "Error: "); \ 
    fprintf(stderr, __VA_ARGS__); \ 
    fprintf(stderr, "\n"); \ 
    abort(); 

あるいは、そのようなものとして使用するGNUスタイル可変引数マクロもあります詳細については

#define error(format, args...) \  
    fprintf(stderr, "Error: "); \ 
    fprintf(stderr, format , ## args); \ 
    fprintf(stderr, "\n"); \ 
    abort(); 

http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

更新

01を参照してください

コンパイラにバリアブルマクロがサポートされていない場合は、機能的なアプローチでva_listに固執してください。定義がヘッダファイルに存在することを望むなら、おそらく静的なインライン関数ですか?

static inline void error(const char *fmt, ...) { 
#define PRINT_ERROR 
    va_list args; 
    fprintf(stderr, "Error: "); 
    va_start(args, fmt); 
    vfprintf(stderr, fmt, args); 
    va_end(args); 
    fprintf(stderr, "\n"); 
    abort(); 
#endif 
} 
+0

@shawnchin:ありがとう。私はMSVC6.0、MSVS-2005コンパイラで試しましたが、可変引数マクロをサポートしていないようです。私はGCCがサポートしていると思いますが、これをサポートするコンパイラベースのコンパイラを知っていますか? – goldenmean

+0

@goldenmean:このサイトでは、ISOスタイルのVariadicマクロがMSVS-2005 Visual C++(http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx)で導入されたことを示しています –

+0

@shawnchin:コンパイラがこの可変マクロをコンパイルできるようにするために設定する必要のある、特有のMSVisual Studioプロジェクトオプションはありますか?私はいくつかのオプションを設定しようとしました(例えば、C++のようにコードをコンパイルしてください)これらの可変マクロ拡張を受け入れるようにコンパイラを強制するマクロがありますか? – goldenmean

0

マクロは可変引数をサポートしていませんが、とにかくva_listを使用すると、ここでは動作しません。これはvariadic 関数引数でのみ機能します。

どうしてあなたはマクロと結びついて機能しますか?

1

ここにはarticle with some examples on variable arguments used in a macroがあります。それはあなたが探しているものを行う必要があるように見えます。マクロに__VA_ARGS__を使用できます。

どのコンパイラを使用していますか?

+0

正常に動作するようです。マクロと完全に良い関数呼び出しを置き換えるのはなぜですか?インラインのようなものではなく、このコードはパフォーマンスや何かに何らかの違いをもたらすでしょう。ちょうどいいコードをとり、それを駄目にするだけです。 – Glen

0

多くのコンパイラは、このように、GNUスタイルの可変引数マクロをサポートしています。

#define error(format,args...) do { \ 
    fprintf(stderr, "error: " format "\n", ##args); \ 
    abort(); \ 
} while(0) 

ただし、移植性を目指した場合、可変引数マクロを使用しないでください。

+0

@Laalto:ありがとう。私はMSVC6.0、MSVS-2005コンパイラで試しましたが、可変引数マクロをサポートしていないようです。私はGCCがサポートしていると思いますが、これをサポートするコンパイラベースのコンパイラを知っていますか? – goldenmean

+0

私はこのコンストラクトをMetrowerks CodeWarriorとWindows上のGCCの様々なフレーバーで使用しました。 – laalto

0

あり、あなたが欲しいものを行い、共通の延長だ、単に書く:

#define error(...) (fputs("Error: ",stdout),printf(__VA_ARGS__),puts("")) 

しかしsome problems__VA_ARGS__を使用してあります

#define error(args...) (fputs("Error: ",stdout),printf(args),puts("")) 

C99ユーザーも言うことができます。幸いにもそれに対処するためのGCC拡張がありますが、コンパイラ固有の拡張を使用することに戻り、args...モードがより広く利用可能になります。

関連する問題