Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
内联函数有地址吗? 在《C++程序设计语言》一书的7.1.1节中作者指出:_C++_Inline - Fatal编程技术网

内联函数有地址吗? 在《C++程序设计语言》一书的7.1.1节中作者指出:

内联函数有地址吗? 在《C++程序设计语言》一书的7.1.1节中作者指出:,c++,inline,C++,Inline,“内联函数仍然有唯一的地址,内联函数的静态变量也有唯一的地址” 我很困惑。如果我有一个内联函数,那么它就不能有地址。这种情况在C语言中也会发生吗?内联属性只是提示编译器应该尝试内联函数。仍然可以获取函数的地址,在这种情况下,编译器还需要发出非内联版本 例如: #include <stdio.h> inline void f() { printf("hello\n"); } int main() { f(); void (*g)() = f; g()

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


我很困惑。如果我有一个内联函数,那么它就不能有地址。这种情况在C语言中也会发生吗?

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

例如:

#include <stdio.h>

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

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

如您所见,首先调用
put()
,然后调用
L_uuz1fv()
(这是
f()
的损坏名称)。

函数的内联扩展没有地址,但如果该函数有静态变量,则该变量确实有地址。静态变量基本上只是一个全局变量,其名称仅在本地可见(即在定义它的范围内)。内联函数中的其他变量可能在堆栈上分配(就像它不是内联扩展时一样),或者它们可能只存在于机器寄存器中。重要的一点是,它们仍然是独立的变量,并且必须像函数根本没有被内联扩展一样运行(不像宏,在宏中,需要非常小心地防止多次求值导致问题)。

如果需要,内联函数是有地址的。标准只规定:

具有外部参数的内联函数 链接应具有相同的地址 所有翻译单位


它们可能在某些调用站点内联,但它们仍然作为普通函数存在于地址空间中

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

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

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

我认为这句话需要更多的上下文。“内联函数仍然有一个唯一的变量”没有意义。为什么你不认为内联函数可以有地址?哪个版本?我正在看第三版,看不出它在哪里这么说。书中准确地引用了“特别是,内联函数仍然有一个唯一的地址,内联函数的静态变量也有一个唯一的地址”。这是第7.1.1节中的最后一件事-上一段以“内联说明符是对编译器的提示”开头(我的重点)。第7.1节介绍了静态变量。2@Clifford-我正在看特别版(第三版修改版)-第三版特别版的旧版,缺少一两个附录。“斯特劳斯特鲁普似乎从未掌握过增加版本号的想法。”查尔斯如前所述更正。谢谢:)这是一种体现还是与“仿佛”规则有关?
_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