在C99内联说明符标准中(6.7.4第6段)规定:

"如果翻译中函数的所有文件范围声明 单元包括inline功能说明符而不包括extern, 那么该翻译单元中的定义是inline definition.An inline definition does not provide an external definition for the function,并且不禁止外部 另一个翻译单元中的定义"

然而,当我用godbolt编译以下代码时:

static inline int foo(int a) {
    a = 1;
    return a; }


int main(void){
    return foo(-1);
}

,结果包括外部定义(应该具有内部链接):

foo:  ; an external definition with internal linkage
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     DWORD PTR [rbp-4], 1
        mov     eax, DWORD PTR [rbp-4]
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        mov     edi, -1
        call    foo
        pop     rbp
        ret

I think the definition of function foo() in source code is a inline definition and thus the assembly result should not contain the definition just like when we declare it with raw inline, but it seems not, why?
Note that, if we compile the code following in godbolt:


inline int foo(int a) {
    a = 1;
    return a; }


int main(void){
    return foo(-1);
}

结果将是:

; Here foo() is omitted because inline definition
main:
        push    rbp
        mov     rbp, rsp
        mov     edi, -1
        call    foo
        pop     rbp
        ret

当foo的定义都是内联定义时,为什么foo确实出现在前一个中,而不是在后一个中?

我在谷歌上搜索了很多,有很多关于静态内联的QA,但没有一个提到上面的行为.

推荐答案

您引用的句子出现在引言后面"对于具有外部链接的功能,以下限制适用:".尽管您引用的句子并没有说明限制,但它们正在为限制设置术语定义.我会将它们解释为仅在具有外部联系的功能的背景下.它们不适用于具有内部链接的功能.

C++相关问答推荐

如何确保内存分配在地址附近?

CC crate 示例不会与C函数链接

如何通过Zephyr(Devicetree)在PR Pico上设置UTE 1?

在C中使用动态内存分配找到最小的负数

为什么输出不是从上到下C

GCC预处理宏和#杂注GCC展开

Char变量如何在不使用方括号或花括号的情况下存储字符串,以及它如何迭代到下一个字符?

将数据移动到寄存器时出现分段故障

C语言中神秘的(我认为)缓冲区溢出

CS50判断灯泡运动的问题,判断时多出一个灯泡,但不在终端上

用C++构建和使用DLL的困惑

如何在C宏定义中包含双引号?

unions 的原子成员是个好主意吗?

用C++初始化局部数组变量

&stdbool.h&q;在嵌入式系统中的使用

C程序printf在getchar while循环后不工作

是什么阻止编译器优化手写的 memcmp()?

返回指向函数内声明的复合文字的指针是否安全,还是应该使用 malloc?

运行以下 C 程序时出现分段错误

使用 SDL2 的 C 程序中的内存泄漏