首页 > 解决方案 > 通过宏嵌入代码

问题描述

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

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

你可以在这里运行它

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

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

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

这里有什么问题?

标签: c++c

解决方案


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

有两种方法可以解决这个问题:

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

换句话说:

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

会起作用(包括宏末尾的分号是不可取的——对于类似函数的宏,您通常应该能够做到if(X) MACRO(something); else {},而分号会搞砸)。


推荐阅读