【问题标题】:Passing macro arguments to macro function将宏参数传递给宏函数
【发布时间】:2018-05-16 20:31:07
【问题描述】:

如何将宏参数与另一个整数变量一起传递给宏函数?

#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));

【问题讨论】:

  • 当您使用SUM(FOO, a) 扩展该行时,FOO 直到参数确定后才会扩展。只有 2 个参数,但宏需要 3 个——因此是消息。 FOO 扩展为 1, 2 将在接下来发生。

标签: c function macros arguments parameter-passing


【解决方案1】:

解析宏调用时,不会扩展宏参数。解析宏调用后,宏定义文本中的宏参数的每次使用都将替换为宏扩展的参数,但与### 操作(字符串化和标记粘贴)一起使用的宏参数除外,被宏参数的未扩展文本替换。然后进行###操作,然后再扫描整个宏体。

结果是SUM(FOO, a) 被解析为具有两个参数的aa。由于宏需要三个,因此无法编译。

在某种程度上,您可以通过使用额外一级的宏扩展来解决这个问题:

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

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

现在__VA_ARGS__ 参数的使用(它恰好是一个可变参数,尽管这对扩展顺序绝对没有影响)将在重新扫描替换文本之前扩展,因此FOO 将被调用三个参数。


顺便说一句,在输出行的开头输出换行符是一个坏习惯,总有一天你会遇到麻烦。输出行的末尾应该有一个换行符:

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

通过在开头添加一个换行符来预先写一个空行并没有错,但是无论如何,您几乎总是应该使用\n 来终止输出行。否则:

  1. 可能不会立即写入该行。在发送换行符之前,行缓冲的输出实际上不会发送到输出设备/文件。

  2. 1234563这往往会混淆像readline 这样的行编辑输入库。

【讨论】:

    【解决方案2】:

    单个宏参数可以工作:

    #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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多