用C/C++代码中的定义替换所有函数调用

3
我想知道是否有某种理论/工具可以将包含函数调用的代码片段替换成所有函数调用已被它们对应的代码替换的代码。例如:
main()
{
   fun();
}

fun()
{
   int i;
   fun2();
}

fun2()
{
   int j;
}

转换为

main()
{
   int i;
   int j;
}

我知道有很多要注意的地方,比如本地变量名称、递归调用、外部函数调用等等。我也知道这可能并不实用,但是像这样的东西是否存在呢?即使只是在理论上存在也好。我应该称之为高级预处理器单元 :)

10
我会称它为优化编译器 :) - JoeFish
1
C预处理器做的事情与这非常相似。 - robert
1
如果你保留{},处理本地变量其实很容易,例如main() { {int i;} {int j} } - Fred Foo
2
编译器可以从函数中进行内联代码生成。一些程序验证器也通过这种方式基本上将程序展平。然而,前者通常不会以可读形式公开其中间结果。后者需要相当大的重写才能产生正确类型的结果。 - Jerry Coffin
1
这是哪种语言?你的函数没有返回值,所以它们不符合C或C++。 - juanchopanza
显示剩余6条评论
1个回答

10

编译器通常能够判断何时进行内联,并已经自动执行。您也可以在函数前使用inline关键字建议将函数内联(请注意,它仍然不能强制执行,编译器可能决定避免内联)。手动进行此操作通常不是一个好主意,因为现代编译器倾向于自行确定最佳的内联方式。本文非常好地解释了内联函数,我发现它非常有帮助

编辑1:

有几个原因可以解释为什么要进行内联操作。如果您觉得您的代码被分成了许多不同的函数,导致其清晰度降低并且变得过于冗长,您可以尝试重构工具,例如VAssist X Visual Studio插件提供的工具。虽然该插件实际上并不像您所建议的那样执行操作(我无法想象出一个能够做到的工具),但它可以帮助轻松移动函数/方法,使您可以整理代码。


一件事:使用 inline 是对编译器的建议;它并不强制将函数内联。FAQ-Lite 链接中的问题9.1解释了这一点。 - chris
inline 关键字并不强制内联。它主要用于避免 ODR 违规。 - Cat Plus Plus
1
inline 关键字并不会强制内联。事实上,许多编译器会忽略它作为内联提示的作用,只是依赖于自己的启发式算法。实际上,内联所做的只是允许函数在多个翻译单元中定义,而不会导致链接器错误:https://dev59.com/JHVC5IYBdhLWcg3w4VVz#157929 - bames53
1
有些编译器有像_forceinline这样的东西,它可以强制将函数内联。但并非总是可能的(比如递归函数)。 - jcoder
嗯,安德烈,谢谢,但问题不是关于inline的使用。此外,内联函数在链接的程序中被它们各自的代码替换,我们无法在内联中阅读它们(在高级语言中它们不是内联的)。正如@jerry所说,我想要展开代码。 - Amar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接