在C/C++宏中替换开放括号字符

3

我需要一个宏将__FILE____LINE__传递给一个有默认参数的函数。这个问题开启了一些棘手的事情,因为使用宏定义的默认参数要么不可能实现,要么非常混乱,并且如果可能的话,我需要支持GCC和MSVC:

class Class
{
#ifdef _DEBUG

   int Function(int a, int b = 10, int c = 20) { return a + b + c; }

#else

   int DebugFunction(const char* filename, int lineNo, int a, int b = 10, int c = 20)
   {
      printf("%s (%i) a:%i b:%i c:%i\n", filename, lineNo, a, b, c);
      return a + b + c;
   }

   //Not possible
   #define Function( DebugFunction(__FILE__, __LINE__

#endif
}

我尝试过转义 ( 符号,但没有成功。由于代码库非常庞大,因此修复缺失的默认参数或创建多个宏并不受欢迎。

有什么解决方案吗?


你为什么说“由于默认参数与宏要么不可能,要么非常混乱”?这不是真的,也与你的问题无关。我认为你只是想要一种简单的方法来自动添加__FILE____LINE__到某些函数调用中。这是你的目标吗? - Aaron McDaid
是的,这正是我一直在尝试(并现在已经成功实现)的目标。KerrekSB的解决方案非常有效。我想我在脑海中把它想得比实际复杂了。 - Catch33
4个回答

6
您可以创建一个可变参数宏:
#define Function(...) DebugFunction(__FILE__, __LINE__, __VA_ARGS__)

由于宏无法进行“重载”,因此这可能是您最好的选择。

@Catch33:你不能这样做,也不要费心去尝试。如果你使用不当,编译器会报错的。(当然,ttd的解决方案更好。) - Kerrek SB
@Catch33,宏并不像你想的那样工作。只需尝试一下,无论是否使用默认参数,它都可以正常工作 :-) - Aaron McDaid
1
+1。只要注意,直到有一天您决定给变量a也赋一个默认值,此代码才有效。 - Jens Gustedt
@KerrekSB 嗯,我有点尴尬,也要向您道歉 - 那个方法完全有效。我整天都在做研究(几个资源都说宏的默认参数不可能),但实际上我从未尝试过... - Catch33
@JensGustedt - 已经注意到了。我相信在我计划使用它的真实世界代码中不会出现这种情况,但我会记住的。 - Catch33
显示剩余9条评论

3

一个选项是将你的主函数 Function 重写为这样:

int Function(const char* filename, int lineNo, int a, int b = 10, int c = 20)
{
   #ifdef _DEBUG
       printf("%s (%i) a:%i b:%i c:%i\n", filename, lineNo, a, b, c);
   #endif
   return a + b + c;
}

这样,所有的调用都会进入同一个函数,但该函数的行为取决于您是否设置了_DEBUG标志。这样可以避免默认参数的问题,因为您只需要进行正常的函数调用,并具有条件代码包含,而不是可能需要许多参数的宏。

希望这有帮助!


哈哈,最简单的解决方案通常是最好的! - Kerrek SB
1
虽然这种方法简单而且有效,但我担心团队成员不会喜欢,因为这意味着在巨大的代码库上进行大量查找/替换操作,并且需要在每次使用该函数时强制编写(FILE__,__LINE)。 - Catch33

1

我不是一个很擅长 C++ 的人,但你可以试试这样的代码(伪代码):

#ifdef debug

#define Function(args) _Function(__file__, __line__, (args))
int _Function(char *file, int line, args) { /* code */ }

#else

#define Function(args) _Function(args)
int _Function(args) { /* code */ }

#endif

这个函数本身需要能够接受多个版本的参数,当然;我真的看不出还有其他的方法。


再次,沿着正确的方向,但我无法计算传递的参数数量。 - Catch33
@tbert:为了使其工作,我认为需要这样调用FunctionFunction((arg1, arg2, arg3)) - Emile Cormier
@Catch33:我不确定你所说的“计算参数数量”是什么意思?你是否忽略了我上面的“伪代码”评论? - tbert
@tbert:我并没有攻击你,而是提供了额外的相关信息来帮助OP(以及其他可能会遇到这篇帖子的人)找到解决方案。 :-) - Emile Cormier
@EmileCormier:我并不认为你是,只是想澄清一下 :) - tbert
显示剩余4条评论

1

我不太确定我理解你想做什么,但是一个可变参数宏是否能解决问题?


沿着正确的方向,但是我无法计算传入的可变参数数量以选择正确的宏。 - Catch33
是的,事实证明我根本不需要计算参数的数量。请参考KerrekSB的回复。 - Catch33

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接