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

C++ 函数调用中字符串的变量名,C++;,c++,C++,我正在扩展我们的内部调试库,我遇到了一堵奇怪的墙。我想将变量名输出为字符串。在这个网站上,我发现可以使用宏在文件中执行此操作: #define VarToStr(v) #v ... printf("%s\n", VarToStr(MatName)); 这将输出MatName。但现在让我们通过跨文件的函数来尝试这一点(矩阵是一种定义的类型): 这将输出InputMat,而不是MatName。另一个文件中的函数如何从调用文件中获取变量名 虽然更复杂的解决方案(包装类等)对更大的社区很有用,但我的实

我正在扩展我们的内部调试库,我遇到了一堵奇怪的墙。我想将变量名输出为字符串。在这个网站上,我发现可以使用宏在文件中执行此操作:

#define VarToStr(v) #v
...
printf("%s\n", VarToStr(MatName));
这将输出
MatName
。但现在让我们通过跨文件的函数来尝试这一点(矩阵是一种定义的类型):

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

虽然更复杂的解决方案(包装类等)对更大的社区很有用,但我的实现需要尽量减少对现有代码/类的影响


更新:


受zenith评论的启发,为了比较起见,我实现了他提出的两种解决方案,并使这两种方案都能很快地发挥作用。宏适用于简单的输出,而函数允许更复杂的工作(以及类型检查/重载)。我不知道预处理器宏会如此复杂。我会记住这两个,以备将来使用。谢谢

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

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

一般来说,你不能这样做(在运行时获取变量的名称,例如从它的地址或C++中引用)。 我的重点是Linux:

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

如果所有相关的代码都是用
-g
编译的(以获取调试信息),那么您可以用格式解析调试信息(可能还使用等)。您可能需要花一些时间才能从服务器上的地址获取某些局部变量的名称。这将是一项重要的工作(可能需要数月的工作)。伊恩·泰勒的(GCC内部)可能是一个有用的起点

您还可以开始(假设所有内容都是用
-g
编译的),例如,使用
gdb-p
调试过程

注意,最近的调试器可以用Python或Guile编写脚本,所以实际上为GDB开发Python或Guile函数会更快


<>你也可以简单地添加调试输出,如.< /p>,如C++所述,不支持运行时反射,所以如果你想要一个字符串,它的内容将只在运行时知道(当调用到<代码> PrimMatxs/Cube >时),你需要<强>作为参数< /Struts> < /P>传递它。 因为您总是知道变量的名称,所以不需要
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);
}
现在,在预处理之后,
analysissubgram342
将如下所示:

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

不可能
InputMat
被称为
InputMat
,无论其值来自何处。
C/C++
是未定义的,因为没有排序点(除非您重载了
++
),@Bathsheba ha!好的:p@Bathsheba(一个好的!)重载将只为C++,所以C标签可以被删除?它是一种预处理器功能,不知道作用域或数据类型,因此您无法将其用于所描述的内容。另外,如果有任何需要,还可以使用
const char*
,因为您总是知道变量的名称,所以不需要VarToStr宏。。。使用工具重构时,字符串可能会更新,也可能不会更新。
void AnalysisSubProgram342()
{
    Matrix MatName;
    ...
    printf("MatName\n");
    ... // output InputMat contents
}