通过宏嵌入代码

ROT*_*OGG 0 c c++

我尝试通过使用宏来嵌入代码块,如下所示:

#define RUN_CODE_SNIPPET(c) do {\
  c\
} while(0);
Run Code Online (Sandbox Code Playgroud)

其中'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;
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里运行它

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

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
Run Code Online (Sandbox Code Playgroud)

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

这有什么不对?

PSk*_*cik 5

在括号内传递的逗号被解释为宏参数分隔符,宏只期望一个参数.

有两种解决问题的方法:

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

换一种说法:

#define RUN_CODE_SNIPPET(...) do { __VA_ARGS__; }while(0) 
Run Code Online (Sandbox Code Playgroud)

将工作(包括在宏的末尾的分号是不可取的 - 对于类似函数的宏,你通常应该能够做if(X) MACRO(something); else {},分号会搞砸了).

  • 关于宏定义的尾随分号的好处.当我发表评论时,我错过了. (2认同)