web-dev-qa-db-ja.com

可変長マクロの作成方法(可変個の引数)

特定の数ではなく、任意の数のパラメーターを受け入れるマクロをCで記述したい

例:

#define macro( X )  something_complicated( whatever( X ) )

ここで、Xは任意の数のパラメーターです

whateverはオーバーロードされており、2つまたは4つのパラメーターで呼び出すことができるため、これが必要です。

マクロを2回定義しようとしましたが、2番目の定義が最初の定義を上書きしました!

私が使用しているコンパイラはg ++(より具体的には、mingw)です。

176
hasen

C99の方法。C++コンパイラでもサポートされています。

#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
273
Alex B

__VA_ARGS__はそれを行う標準的な方法です。必要がない場合は、コンパイラ固有のハッキングを使用しないでください。

元の投稿にコメントできないことに本当にイライラしています。いずれにしても、C++はCのスーパーセットではありません。C++コンパイラでCコードをコンパイルするのは本当にばかげています。ドニーがやらないことをしてはいけない。

32
cmccabe

私はそれが可能だとは思わない、あなたは二重括弧でそれを偽造することができた...ちょうどあなたが個別に引数を必要としない限り。

#define macro(ARGS) some_complicated (whatever ARGS)
// ...
macro((a,b,c))
macro((d,e))
25
eduffy
#define DEBUG

#ifdef DEBUG
  #define PRINT print
#else
  #define PRINT(...) ((void)0) //strip out PRINT instructions from code
#endif 

void print(const char *fmt, ...) {

    va_list args;
    va_start(args, fmt);
    vsprintf(str, fmt, args);
        va_end(args);

        printf("%s\n", str);

}

int main() {
   PRINT("[%s %d, %d] Hello World", "March", 26, 2009);
   return 0;
}

コンパイラが可変長マクロを理解しない場合は、次のいずれかを使用してPRINTを削除することもできます。

#define PRINT //

または

#define PRINT if(0)print

最初はPRINT命令をコメントアウトし、2番目はNULL if条件のためにPRINT命令を禁止します。最適化が設定されている場合、コンパイラは次のような決して実行されない命令を取り除く必要があります。if(0)print( "hello world");または((void)0);

10
Symon

ここでg ++について説明しましたが、これはC99の一部であるため、すべてのユーザーで動作するはずです

http://www.delorie.com/gnu/docs/gcc/gcc_44.html

簡単な例:

#define debug(format, args...) fprintf (stderr, format, args)
4
DarenW