内联函数有地址吗?

在“The C ++ Programming Language”一书的第7.1.1节中,作者指出:

“内联函数仍然具有唯一的地址,内联函数的静态变量也是如此”

我很迷惑。 如果我有一个内联函数,那么它就没有地址。 这也发生在C中吗?

inline属性只是编译器的一个提示 ,它应该尝试内联您的函数。 仍然可以获取函数的地址,在这种情况下,编译器还需要发出非内联版本。

例如:

 #include  inline void f() { printf("hello\n"); } int main() { f(); void (*g)() = f; g(); } 

上面的代码打印两次hello

我的gcc编译器(带-O )发出如下代码:

 _main: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp call ___i686.get_pc_thunk.bx "L00000000002$pb": leal LC0-"L00000000002$pb"(%ebx), %eax movl %eax, (%esp) call L_puts$stub ; inlined call to f() call L__Z1fv$stub ; function pointer call to f() (g is optimised away) movl $0, %eax addl $20, %esp popl %ebx popl %ebp ret 

正如您所看到的,首先调用puts()然后调用L__Z1fv() (这是f()的错位名称)。

如果需要,内联函数有地址。 标准只说:

具有外部链接的内联函数在所有翻译单元中应具有相同的地址。

没有矛盾。 在调用内联函数的部分中,可以内联其代码。 在使用指向函数的指针的部分中,可以创建非内联版本以具有地址。

函数的内联扩展没有地址,但如果该函数有静态变量,则变量确实有一个地址。 静态变量基本上只是一个全局变量,其名称仅在本地可见(即,在定义它的范围内)。 内联函数中的其他变量可能会在堆栈上分配(就像它们没有内联展开一样),或者它们可能只存在于机器寄存器中。 重要的是它们仍然是单独的变量,并且必须像函数一样完全没有内联扩展(例如,不同于宏,需要极其小心以防止多个评估引起问题)。

它们可能在某些呼叫站点内联,但它们仍然作为地址空间中的正常function而存在。

我认为你混淆了内联函数对象代码的位置,以及内联的含义。 通常,我们将内联函数可视化为放置在源代码级别的调用函数中。 本书所说的是变量名称,包括在内联函数中使用静态,被视为与函数实际上是典型的独立函数一样。

此外,使用内联关键字处理函数并不能保证它们将被内联,并且对于它们不能的情况(例如在需要地址时),将生成非内联版本。