2017-12-03 20 views
1

マクロ関数に別の整数変数とともにマクロ引数を渡すにはどうすればよいですか? マクロ関数へのマクロ引数の受け渡し

#define SUM(X, Y, Z) X + Y + Z 
#define FOO 1, 2 

void print(int a, int b) 
{ 
    printf("Sum: %d", a + b); 
} 

int main(void) 
{ 
    // Normal function works as expected 
    print(FOO); 

    // Macro function not working 
    int a = 3; 
    printf("\nMacro Sum: %d", SUM(FOO, a)); 

    return 0; 
} 

私は、出力があることを期待:

Sum: 3 
Macro Sum: 6 

しかし、私は次のエラーを取得する:

main.c:18:41: error: macro "SUM" requires 3 arguments, but only 2 given 
    printf("\nMacro Sum: %d", SUM(FOO, a)); 
+0

'SUM(FOO、a)'を使ってその行を展開すると、引数が決まるまで 'FOO'は展開されません。引数は2つしかありませんが、マクロは3を期待しています。したがって、メッセージです。次に、 'FOO'の' 1,2への展開が起こります。 –

答えて

0

シングルマクロ引数は動作します:

#define SUM(X, Y, Z) X + Y + Z 
#define FOO1 (1) 
#define FOO2 (2) 

void print(int a, int b) 
{ 
    printf("Sum: %d", a + b); 
} 

int main(void) 
{ 
    // Normal function works as expected 
    print(FOO1,FOO2); 

    int a = 3; 
    printf("\nMacro Sum: %d", SUM(FOO1, FOO2, a)); 

    return 0; 
} 

出力:マクロ呼び出しが解析されるとき

Sum: 3 
Macro Sum: 6 
1

マクロの引数は展開されません。マクロ呼び出しが解析された後、マクロ定義テキスト内のマクロパラメータの各使用は、マクロ展開された引数に置き換えられます。ただし、#または##操作(文字列化およびトークンペースト)で使用されるマクロパラメータは、拡張されていないマクロ引数のテキスト。次に、#および##の操作が実行され、マクロ本体全体がもう一度スキャンされます。

結果として、SUM(FOO, a)は2つの引数を持つ解析されます。マクロは3つ必要なので、コンパイルしないでください。

あなたはマクロ展開の1つの余分レベルを使用することによって、ある程度まで、この問題を回避することができます

#define CALL(macro, ...) macro(__VA_ARGS__) 

printf("\nMacro Sum: %d", CALL(SUM, FOO, a)); 

今では絶対になりますが、可変引数パラメータであることを起こる__VA_ARGS__パラメータ(の使用置き換えテキストが再スキャンされる前に展開順序との違いはありません)、FOOが3つの引数で呼び出されます。


ところで、出力行の先頭に改行文字を出力することは、いつかあなたを困らせる悪い習慣です。出力ラインは、行の末尾に改行を持っている必要があります。

printf("Macro Sum: %d\n", CALL(SUM, FOO, a)); 

と間違って何もにも先頭に改行を入れて事前に空白行を書き、関係なく、あなたはほとんど常にはずもありません外字の行を\nで終了します。そうでない場合:

  1. 行がすぐに書き込まれないことがあります。ラインバッファされた出力は、改行が送信されるまで出力装置/ファイルに実際には送られません。

  2. プログラムがコンソールアプリケーションで、stdoutを正しく閉じることなく終了した場合は、最後の出力行がある場合は次のシェルコマンドを最後に入力します。これは、readlineのようなライン編集入力ライブラリを混乱させる傾向があります。

関連する問題