我有以下要求:
- 在任何函数的入口和导出点添加文本。
- 除了从上面插入之外,不更改源代码(因此没有预处理器或任何东西)
例如:
void fn(param-list)
{
ENTRY_TEXT (param-list)
//some code
EXIT_TEXT
}
但不仅在如此简单的情况下,它还可以使用预处理器指令运行!
示例:
void fn(param-list)
#ifdef __WIN__
{
ENTRY_TEXT (param-list)
//some windows code
EXIT_TEXT
}
#else
{
ENTRY_TEXT (param-list)
//some any-os code
if (condition)
{
return; //should become EXIT_TEXT
}
EXIT_TEXT
}
所以我的问题是:有正确的方法吗?
我已经尝试过使用编译器使用的解析器进行一些工作,但由于它们都依赖于在解析之前运行预处理器,因此它们对我来说毫无用处。
此外,一些不需要预处理器的标记生成解析器有些无用,因为它们生成标记的内存映射,然后生成完整的新源代码,而不仅仅是插入文本。
我正在做的一件事是尝试使用 FLEX(或 JFlex),如果这是一个有效的选项,我将不胜感激。 ;-)
编辑: 澄清一点:目的是允许诸如堆栈跟踪之类的东西。 我想跟踪每个函数调用,为了遵循调用层次结构,我需要在函数的入口点和函数的导出点放置一个宏。 这将构建函数调用跟踪。 :-)
编辑2:特定于编译器的选项不太合适,因为我们有许多不同的编译器可供使用,而且许多编译器可能不受任何工具的良好支持。
最佳答案
不幸的是,你的想法不仅不切实际(C++ 解析起来很复杂),而且注定会失败。
您遇到的主要问题是异常将完全绕过您的 EXIT_TEXT
宏。
您有多种解决方案。
正如已经指出的,第一个解决方案是使用依赖于平台的方式来计算堆栈跟踪。它可能有点不精确,特别是因为内联:即,小函数在其调用者中内联,它们不会出现在堆栈跟踪中,因为在程序集级别没有生成函数调用。另一方面,它的应用广泛,不需要对代码进行任何改动并且不会影响性能。
第二种解决方案是仅在进入时引入一些内容,并使用 RAII 来完成退出工作。比您的方案好得多,因为它自动处理多个返回和异常,但它遇到相同的问题:如何自动执行插入。为此,您可能需要在 AST 级别进行操作,并修改 AST 以引入您的小 gem。您可以使用 Clang(查找 c++11 迁移工具以获取大规模重写的示例)或使用 gcc(使用插件)来完成此操作。
最后,您还有手动注释。虽然它可能看起来动力不足(并且需要大量工作),但我要强调的是,您不会将日志记录留给工具...我看到手动执行此操作的 3 个优点:您可以避免在性能敏感部分引入这种开销,您可以仅保留大参数的“摘要”,您可以根据当前函数感兴趣的内容自定义摘要。
关于c++ - 在函数之间将文本插入到 C++ 代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16602752/