我正在进行调试/日志记录程序,并且想知道是否可以创建一个我可以在每个函数中粘贴的宏,并且每次调用函数时它都会打印函数名和参数值。函数名称可以在编译时恢复,问题是如何打印参数值?
更新:我记得读过一篇文章来获取参数,但是调用汇编代码和工作操作堆栈指针,这不是跨平台兼容的 - 我需要的东西。
答案 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)
答案 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链接非常有用。它描述了三种在运行时获取应用程序回溯的方法:
答案 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。