我怎么知道内联函数是否在被调用的地方被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生成汇编代码)来看到汇编代码,你可以看到你的函数是否被内联了。

  1. 看到对象文件的大小,它们在内联和非内联之间是不同的
  2. 使用nm“obj_file”| grep“fun_name”,它们也不同
  3. gcc -Winline -O1
  4. 与汇编代码进行比较