可以将代码字符串传递给 C\C++ 宏吗?

Can one pass a code string into a C\C++-macro?

例如,我想制作一个调试宏,在尝试执行它之前打印一个代码字符串。我想它应该看起来像那样

#define TRACE(string) printf("Trying to execute: %s\n",\"string\"); \
                      string

...

void foo() {
  printf("1\n");
}
void bar() {
  printf("2\n");
}

int main() {
  ...
  foo();
  TRACE(bar(););
  ...
}

具有预期输出

...
1
Trying to execute: bar();
2
...

好吧,这不是一个人的做法:编译器抱怨非法语法。有没有办法做到这一点?

您需要使用字符串化 #:

#define TRACE(string) printf("Trying to execute: %s\n",#string); \
                      string

完整示例:

#include <stdio.h>

#define TRACE(string) printf("Trying to execute: %s\n",#string); \
                          string

void foo() {
  printf("1\n");
}
void bar() {
  printf("2\n");
}

int main() {

  foo();
  TRACE(bar(););
}

输出:

1
Trying to execute: bar();
2

live example on ideone

您必须使用 "stringification" 运算符 #,这将导致替换为 "string"

#define TRACE(string) printf("Trying to execute: %s\n", #string); \
                      string

除了前面的答案之外,将宏包裹在 do { /* ... */ } while(0) 结构周围,如:

#define TRACE(string) do { \
                          printf("Trying to execute: %s\n", #string); \
                          string \
                      } while(0)

否则可能会出错,例如

if(condition)
    TRACE(foo();)

如果您不将其包裹在 do { /* ... */ } while(0) 结构中,即使 condition 为假,也会调用 foo()。如果你后面有一个else语句,它甚至会导致语法错误。

有关详细信息,请参阅 Why use apparently meaningless do-while and if-else statements in macros?