繁体   English   中英

函数调用中的字符串变量名,C ++

[英]Variable name to string in function call, C++

我正在扩展我们的内部调试库,而且我遇到了一个奇怪的问题。 我想输出一个变量名作为字符串。 从本网站的其他地方 ,我发现可以在文件中使用宏来执行此操作:

#define VarToStr(v) #v
...
printf("%s\n", VarToStr(MatName));

这输出MatName 但现在让我们通过跨文件的函数来尝试这个(Matrix是一个定义的类型):

// DebugHelpers.h
#define VarToStr(v) #v
...
void PrintMatrix(const Matrix &InputMat)
{
    printf("%s\n", VarToStr(InputMat));
    ... // output InputMat contents
}

// DataAnalysis.cc
#include DebugHelpers.h
...
void AnalysisSubProgram342()
{
    Matrix MatName;
    ...
    PrintMatrix(MatName);
}

这输出InputMat ,而不是MatName 另一个文件中的函数如何从调用文件中获取变量名?

虽然更复杂的解决方案(包装类等)对更大的社区有用,但我的实现需要最小化对预先存在的代码/类的影响。


更新:

受天顶评论的启发,我为了比较而实施了他提出的两个解决方案,并且快速完成了工作。 该宏适用于简单输出,而该功能允许更复杂的工作(以及类型检查/重载)。 我不知道预处理器宏可能如此复杂。 我会记住两者以备将来使用。 谢谢 !

你不能。 C和C ++都不会在运行时保留变量名。

您的所有宏都在替换在编译时发生的文本。

正如其他人所提到的,C ++不支持运行时反射,因此如果你想拥有一个只在运行时知道其内容的字符串(即调用PrintMatrix时候),你需要将它作为参数传递

而且因为你总是知道变量的名称是什么,所以你不需要VarToStr宏:

// DebugHelpers.h
void PrintMatrix(const Matrix &InputMat, const char* MatName)
{
    printf("%s\n", MatName);
    ... // output InputMat contents
}

// DataAnalysis.cc
#include DebugHelpers.h
...
void AnalysisSubProgram342()
{
    Matrix MatName;
    ...
    PrintMatrix(MatName, "MatName");
}

但还有另一种选择 :让PrintMatrix成为一个宏本身,因为它只是一个调试的东西:

// DebugHelpers.h
#define PRINT_MATRIX(InputMat)\
printf(#InputMat "\n");\
... // output InputMat contents


// DataAnalysis.cc
#include DebugHelpers.h
...
void AnalysisSubProgram342()
{
    Matrix MatName;
    ...
    PRINT_MATRIX(MatName);
}

现在经过预处理后, AnalysisSubProgram342将如下所示:

void AnalysisSubProgram342()
{
    Matrix MatName;
    ...
    printf("MatName\n");
    ... // output InputMat contents
}

通常,您不能这样做(在运行时获取变量的名称,例如从其地址或在C ++中获取它的引用)。

我专注于Linux:

但是,在Linux(和基于GNU glibc的系统)上,对于全局变量(和函数),您可以使用GNU特定的dladdr(3)函数。

如果所有相关代码都是使用-g编译的(以获取调试信息),则可能会以DWARF格式解析调试信息(也许还使用__builtin_frame_address等)。 有些痛苦,您可能能够从调用堆栈上的地址获取一些局部变量的名称。 这将是一项重大的努力(可能是几个月的工作)。 Ian Taylor的libbacktrace (在GCC内部)可能是一个有用的起点。

您也可以启动(假设所有内容都使用-g编译),例如popen(3)gdb -p调试过程。

请注意,最近的GDB调试器可以在Python或Guile中编写脚本,因此实际上,为GDB开发Python或Guile函数会更快。

您也可以像这里一样添加调试输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM