通过宏嵌入代码

时间:2018-08-11 21:26:46

标签: c++ c

我尝试通过使用这样的宏来嵌入代码块:

#define RUN_CODE_SNIPPET(c) do {\
  c\
} while(0);

其中'c'是封闭在'{}'内的代码块

这里是使用方法

#include <stdio.h>

#define RUN_CODE_SNIPPET(c) do {\
  c\
} while(0);

int main(int argc, char *argv[]) {

  RUN_CODE_SNIPPET({
    //const char *message   = "World";  
    const char  message[] = {'w', 'o', 'r', 'l', 'd', '\0'};  
    printf("%s\r\n", message);
  });

  return 0;
}

您可以在这里here

运行它

但是当我使用初始化列表格式时,会出现编译器错误

test.c: In function ‘main’:
test.c:13:4: error: macro "RUN_CODE_SNIPPET" passed 6 arguments, but takes just 1
    });
    ^
test.c:9:3: error: ‘RUN_CODE_SNIPPET’ undeclared (first use in this function)
RUN_CODE_SNIPPET({   
               ^~~~~~~~~~~~~~~~
test.c:9:3: note: each undeclared identifier is reported only once for each
function it appears in

似乎编译器将初始化程序列表中的每个元素都用作宏本身的参数。字符串初始化程序可以正常工作。

这是怎么了?

1 个答案:

答案 0 :(得分:5)

您在括号内传递的逗号被解释为宏参数分隔符,而宏只需要一个参数。

有两种解决方法:

  1. 将包含逗号的参数括起来,即传递(a,b,c)而不是a,b,c(在您的情况下不适用,因为您的参数不是表达式)
  2. 使用可变参数宏参数(...-> __VA_ARGS__

换句话说:

#define RUN_CODE_SNIPPET(...) do { __VA_ARGS__; }while(0) 

将起作用(不建议在宏末尾包含分号-对于类似函数的宏,通常应该能够执行if(X) MACRO(something); else {},而分号会弄乱它)。