C 是否可以将代码块作为宏参数传递?

C 是否可以将代码块作为宏参数传递?,c,C,我想用一些样板代码来包装一些代码行,那么我应该通过将多行代码作为宏参数传递来完成吗,如下所示: #define safeRun(x) if (ValidationOK()) {x} int main(int argc, char **argv) { safeRun( foo(); bar(); ) } 非常感谢。使用\字符在宏定义中“转义”换行符。使用可变宏参数在包含代码行的参数中支持逗号。(此功能是C99的一部分,但也存在于许多不兼容的编译

我想用一些样板代码来包装一些代码行,那么我应该通过将多行代码作为宏参数传递来完成吗,如下所示:

#define safeRun(x) if (ValidationOK()) {x} 

int main(int argc, char **argv) {
    safeRun(
        foo();
        bar();
    )
}

非常感谢。

使用
\
字符在宏定义中“转义”换行符。使用可变宏参数在包含代码行的参数中支持逗号。(此功能是C99的一部分,但也存在于许多不兼容的编译器中。)

请注意,反斜杠和换行之间不能有空格


标准警告:宏是最容易泄漏的封装形式;如果可能,请使用任何其他构造。

如前所述,您的代码将运行逗号运算符(但不像前面所说的那样,在函数参数列表中使用逗号)

假设您使用C99,您甚至可以通过宏中的变量参数来避免该问题:

#define safeRun(...) if (ValidationOK()) {__VA_ARGS__}

int main(int argc, char **argv) {
    safeRun(
        foo(a, b),
        bar(c, d);
    )
}
现在,就预处理器而言,宏有两个参数,由逗号分隔,但它们可以按照您的需要进行处理。以下是
gcc-E
输出:

# 1 "x3.c"
# 1 "<command-line>"
# 1 "x3.c"


int main(int argc, char **argv) {
    if (ValidationOK()) {foo(a, b), bar(c, d);}



}
#1“x3.c”
# 1 ""
#1“x3.c”
int main(int argc,字符**argv){
if(ValidationOK()){foo(a,b),bar(c,d);}
}

你的建议是否是一个好主意是一个单独的讨论;这些机制或多或少会使它工作。

类似宏的功能非常糟糕,原因有很多。解决这个问题的更好方法是使用实函数

start_safe();
  foo();
  bar();
stop_safe();

正如@Potatoswatter所说,您可以使用反斜杠:

#define safeRun(x) \
  [Validation code]; \
  if (ValidationOK()) \
      {x} \
  [Finishing code]; \
但如果您以这种方式使用它,这可能会成为一个问题:

if (x)
  safeRun(y);
else
  ...
要解决此问题,请执行以下操作:

#define safeRun(x) \
  do { \
      [Validation code]; \
      if (ValidationOK()) \
          {x} \
      [Finishing code]; \
  } while(0);

谢谢-是否也可以“伪造”花括号?理想情况下,我希望它看起来像
safeRun{…}
而不是
safeRun(…)
;预处理器需要括号而不是大括号。但是,如果您真的愿意,可以在参数列表中使用大括号。您可能希望使用双哈希来避免问题或尾随的coma###uu VA_uargs uu.@ant2009不确定您的意思。据我记忆所及,这是一个GCC扩展,但它只在将
\uu VA\u ARGS\uu
传递给函数时起作用。但随后我必须在主代码中单独处理
if
条件,这开始破坏定义这些宏进行整理的目的。@MiloChen如果删除分号并使用“regular”宏
START_SAFE foo();bar();停止\u SAFE
则这是一种有效的设计模式,具有避免
\uu VA\u ARGS\uuu
@MiloChen的优点。那么主要问题可能只是宏在开始时是多余的。您也可以通过使用两个函数指针作为参数的函数来解决这个问题,但这也让人觉得不必要的复杂。保持代码简单!一个示例描述了您搜索的内容:
#define safeRun(x) \
  do { \
      [Validation code]; \
      if (ValidationOK()) \
          {x} \
      [Finishing code]; \
  } while(0);