我怎么知道内联函数是否在被调用的地方被replace了?
我知道内联函数要么被replace,要么被调用,或者像一个正常的函数一样。
但是,我怎么知道内联函数实际上是否在被调用的地方被replace,因为内联函数是在编译时处理的决定?
在运行时编程,你不能。
事情的真相是: 你不需要知道
编译器可以selectinline
未标记为inline
函数或忽略显式inline
标记的函数,这完全是编译器的愿望(阅读智慧 )。您应该相信编译器会明智地做好工作。 大多数主stream的编译器都会很好的完成他们的工作。
如果您的问题纯粹是从学术的angular度来看,那么有几个选项可供select:
分析生成的汇编代码:
您可以检查汇编代码,以检查函数代码是否在调用点处内联。
如何生成汇编代码?
对于gcc:
编译时使用-S
开关。
例如:
g++ -S FileName.cpp
生成的汇编代码被创build为文件FileName.s
。
对于MSVC:
从命令行使用/ FA切换 。
在生成的汇编代码查找中是否存在特定函数的call
汇编指令。
使用编译器特定的警告和诊断:
如果某些编译器不符合内联函数请求,则会发出警告。
例如,在gcc中,如果编译器不内联已声明为内联的函数, -Winline
命令选项将发出警告。
查看GCC文档以获取更多详细信息:
-Winline
警告如果声明为内联的函数不能内联。 即使使用此选项,编译器也不会警告内联函数在系统头文件中声明的函数失败。
编译器使用各种启发式来确定是否内联一个函数。 例如,编译器考虑了内联函数的大小以及当前函数中已经完成的内联量。 因此,源程序中看似微不足道的变化可能会导致由
-Winline
产生的警告出现或消失。
检查生成的代码。 如果function被扩展,你会看到它的身体,而不是一个call
或类似的指令。
您可以使用工具在Linux上从诸如nm
目标文件中列出符号。 如果函数被内联,将不会以nm
输出列出 – 它成为其他函数的一部分。 你也不能在debugging器中通过名称来放置这个函数的断点。
有了gdb,如果你不能调用函数,它的一个可能的含义就是函数是内联的。 翻转推理,如果你可以在gdb中调用一个函数,意味着这个函数没有标记为内联。
如果您需要确保函数内联,并确定使用MS VC ++中的专有扩展, 请检查__forceinline
声明器 。 编译器将内联该函数,或者如果它属于已logging的特殊情况列表,则会收到警告 – 所以您将知道内联状态。
不以任何方式赞同。
内嵌或不是函数的决定是由编译器做出的。 而且由于它是由编译器生成的,所以是的,只能在编译时进行。
所以,如果你可以通过使用-S选项(用gcc -S生成汇编代码)来看到汇编代码,你可以看到你的函数是否被内联了。
- 看到对象文件的大小,它们在内联和非内联之间是不同的
- 使用nm“obj_file”| grep“fun_name”,它们也不同
- gcc -Winline -O1
- 与汇编代码进行比较