宏从函数中获取函数名称和参数值

时间:2012-03-01 19:44:57

标签: c++ c macros

我正在进行调试/日志记录程序,并且想知道是否可以创建一个我可以在每个函数中粘贴的宏,并且每次调用函数时它都会打印函数名和参数值。函数名称可以在编译时恢复,问题是如何打印参数值?

更新:我记得读过一篇文章来获取参数,但是调用汇编代码和工作操作堆栈指针,这不是跨平台兼容的 - 我需要的东西。

6 个答案:

答案 0 :(得分:2)

您可以使用__FUNCTION____func__宏作为函数名称。对于参数,我认为没有内置的宏来实现这一点。

其他有用的宏是__LINE____FILE__

编辑:

__FUNCTION____func__不是标准的一部分,但广泛支持。

16.8 处理预定义的宏:

__cplusplus
__DATE__
__FILE__
__LINE__
__STDC_HOSTED__
__TIME__

和实现定义的宏:

__STDC__
__STDC_VERSION__
__STDC_ISO_10646__

答案 1 :(得分:1)

对于函数名称,您可以使用标准(自C99)标识符__func__

在C ++中,GNU扩展标识符__PRETTY_FUNCTION__也将打印参数类型。

答案 2 :(得分:0)

没有可移植的方法来获取所有参数值并打印它们 - 你当然不能从宏中做到这一点。您可能必须使用其他方法来实现您想要的目标。

答案 3 :(得分:0)

Here是一些使用宏进行调试的示例和技巧。 MS specificGNU

列表

答案 4 :(得分:0)

您可以使用variadic macro,然后将字符串格式和函数参数传递给它。每个函数的宏都不会完全相同(因为每个函数可能具有不同的参数),但是大多数工作在于复制粘贴上面一行的参数。

如果您的功能签名是:

void func(char *param1, int param2);

您的宏将类似于:

PROFILE_FUNC(__FILE__, __LINE__, "param1 = %s, param2 = %d", param1, param2);

PROFILE_FUNC(__ FILE__,__LINE __,...之后的部分将是可变的。请查看链接中具体如何执行此操作。

如果七年来没有人觉得更好,那一定是要走的路。如果可以找到__PRETTY_FUNCTION__如何获取参数类型,则可以进一步使它自动化。

编辑

This链接非常有用。它描述了三种在运行时获取应用程序回溯的方法:

  1. gcc内置宏__builtin_return_address
  2. glibc backtrace backtrace_symbols
  3. libunwind

答案 5 :(得分:0)

C宏系统无法隐式引用参数。您必须将它们传递给它。

由于一个小的win宏可以计算其参数,所以它将是TRACE(foo,bar)而不是TRACE2,TRACE3等。这并不比在函数开始时编写TRACE()显着差。

实际打印这些值就可以了。重载运算符<<或与_Generic手动滚动,具体取决于语言。

干净地做这种事情,例如要推断参数,可通过代码生成器访问动态地打开和关闭打印。两种样式: 1 /解析C或特定注释。参见swig,doxygen。 2 /从其他东西生成日志记录功能和C

解析C似乎更常见。可能是因为您可以轻松地将其添加到现有代码中。从另一个输入生成更容易可靠地完成。以XML / JSON的形式编写函数名称,参数列表,包含实现的字符串。除了模板之外,我还喜欢生成C和元数据的python和lua脚本。另请参阅LLVM的tablegen。