简体   繁体   English

内联函数有地址吗?

[英]Do inline functions have addresses?

In section 7.1.1 of the book "The C++ Programming Language" the author states: 在“The C ++ Programming Language”一书的第7.1.1节中,作者指出:

"inline function still has a unique address and so do the static variables of an inline function" “内联函数仍然有一个唯一的地址,内联函数的静态变量也是如此”

I am confused. 我很迷惑。 If I have an inline function then it can't have address. 如果我有一个内联函数,那么它就没有地址。 Does this happen in C also? 这也发生在C吗?

The inline attribute is just a hint to the compiler that it should try to inline your function. inline属性只是编译器的一个提示 ,它应该尝试内联您的函数。 It's still possible to take the address of the function, and in that case the compiler will also need to emit a non-inline version. 仍然可以获取函数的地址,在这种情况下,编译器还需要发出非内联版本。

For example: 例如:

#include <stdio.h>

inline void f() {
    printf("hello\n");
}

int main() {
    f();
    void (*g)() = f;
    g();
}

The above code prints hello twice. 上面的代码打印两次hello

My gcc compiler (with -O ) emits code something like this: 我的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

As you can see, there is first a call to puts() and then a call to L__Z1fv() (which is the mangled name of f() ). 正如您所看到的,首先调用puts()然后调用L__Z1fv() (这是f()的错位名称)。

Inline functions are have addresses if you need one. 如果需要,内联函数具有地址。 Standard only says that: 标准只说:

An inline function with external linkage shall have the same address in all translation units. 具有外部链接的内联函数在所有翻译单元中应具有相同的地址。

There is no contradiction. 没有矛盾。 In parts where an inline function is called, its code can be inlined. 在调用内联函数的部分中,可以内联其代码。 In parts where you use a pointer to function, a non-inline version can be created to have an address. 在使用指向函数的指针的部分中,可以创建非内联版本以具有地址。

The inline expansion of the function doesn't have an address, but if that function has a static variable, the variable does have an address. 函数的内联扩展没有地址,但如果该函数有静态变量,则该变量确实有一个地址。 A static variable is basically just a global variable whose name is only visible locally (Ie, within the scope at which it is defined). 静态变量基本上只是一个全局变量,其名称仅在本地可见(即,在定义它的范围内)。 Other variables in an inline function might be allocated on the stack (like they would be if it wasn't expanded inline) or they might just live in machine registers. 内联函数中的其他变量可能在堆栈上分配(就像它们没有内联展开一样),或者它们可能只存在于机器寄存器中。 The important part is that they are still separate variables, and have to act just like the function hadn't been expanded inline at all (unlike, for example, macros, where extreme care is needed to prevent multiple evaluations from causing problems). 重要的是它们仍然是单独的变量,并且必须像函数一样完全没有内联扩展(例如,不同于宏,需要极其小心以防止多个评估引起问题)。

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

I think you are confusing the location of the inlined functions object code, with the implications of inlining. 我认为你混淆了内联函数对象代码的位置,以及内联的含义。 Typically we visualize inlined functions as being placed within the calling function at the source code level. 通常,我们将内联函数可视化为放置在源代码级别的调用函数内。 What the book is saying is that the variable names, including the use of static within inline functions, are treated just the same as if the function was in fact your typical, stand-alone function. 本书所说的是变量名称,包括内联函数中静态的使用,被视为函数实际上是典型的独立函数。

Furthermore, treatment of functions with the inline keyword, does not guarantee that they will be inlined, and for instances where they cannot (such as when requiring an address), a non-inlined version will be generated. 此外,使用inline关键字处理函数并不保证它们将被内联,并且对于它们不能的情况(例如在需要地址时),将生成非内联版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM