gpt4 book ai didi

c++ - C和C++中inline-keyword的区别

转载 作者:行者123 更新时间:2023-12-04 11:56:37 26 4
gpt4 key购买 nike

考虑以下带有 inline 的 C++ 代码-功能:

// this function is in a header-file:
// recursion prevents inlining
inline int calc(int k){
if(k<=1) return 1;
return calc(k-1)+calc(k-2);
}

// this function is in a source-file:
int fun(int k){
return calc(k);
}
这里我使用递归来模拟编译器无法内联函数 calc 的情况。 .
生成的程序集(使用 -Os 编译,参见 live on https://godbolt.org/ ):
...
.weak calc(int)
.type calc(int), @function
calc(int):
// some assembler


.text
.globl fun(int)
.type fun(int), @function
fun(int):
...
jmp calc(int)
正如预期的那样,编译器无法内联 calc ,因此为它发出了代码,但由于 inline -keyword 它成为一个弱符号。
编译与 C 相同的代码,会产生不同的结果(使用 -Os ,参见 live on https://godbolt.org/ ):
.Ltext0:
.globl fun
.type fun, @function
fun:
...
jmp calc
最显着的区别:没有为 calc 发出代码,所以基本上链接器将无法链接可执行文件,如 calc 的定义不见了。
显然, inline与 C++ 相比,在 C 中意味着不同的东西。 inline有什么区别在 C 中与 C++ 相比?怎么定义 calc应该完成,它可以同时在 C 和 C++ 的头文件中使用?

最佳答案

inline -keyword 在 C 和 C++ 中具有相同的目标:在编译时在多个翻译单元中提供函数的定义,这些语言使用不同的方法来应对其后果 - 在不同的翻译单元中对同一符号的多个定义。
当 C 或 C++ 编译器真正内联 inline 时-function 在翻译单元中,不再需要它的定义,也不会发出相应的符号。例如这里:

inline int fun(){return 2;}

int doit(){
return fun();
}
生成的汇编程序是 ( live )
doit():
movl $2, %eax
ret
但是,当函数没有被内联时,C++ 标准规定了以下内容:
  • 只要每个定义出现在不同的翻译单元中并且所有定义都相同,程序中可能会有多个内联函数的定义。
  • 该函数在每个翻译单元中具有相同的地址。

  • 这或多或少描述了一个 weak symbol - 毫不奇怪,C++ 编译器会在 OP 的代码中发出一个弱符号 - 它必须这样做,因为 C++ 标准不保证该符号将在另一个翻译单元中定义。
    另一方面,C 标准保证,内联函数的定义必须在另一个翻译单元中提供(即具有外部链接),因此(为了避免同一符号的多个定义)没有为内联函数 - 它只是被调用。
    因此,必须有一个 c 文件,其中函数通过
    inline int calc(int k)
    这不适用于拥有仅 header 库的想法。另一种方法是,通过 static 使用内部链接。 - 关键字,即
    static inline int calc(int k){
    if(k<=1) return 1;
    return calc(k-1)+calc(k-2);
    }
    这将在每个翻译单元(如果没有内联)中发出一个本地符号,与编译为 C 还是 C++ 无关。这意味着,同一函数有多个定义(即在每个翻译对象中,函数具有不同的地址),这可能会导致更大的可执行文件,并且与 C++ 的默认行为相比是一个挫折。
    另一种方法是使用以下定义 inline :
    #ifdef __cplusplus
    #define INLINE inline
    #else
    #define INLINE static inline
    #endif
    并用作
    INLINE int calc(int k){
    ...
    }

    关于c++ - C和C++中inline-keyword的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68004269/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com