为什么“static”说明符会为内联函数生成外部定义?

问题描述 投票:0回答:1

在内联说明符的 C99 标准(6.7.4 第 6 段)中指出:

“如果翻译中函数的所有文件范围声明 单元包含 inline 函数说明符,不带 extern, 那么该翻译单元中的定义是一个 inline 定义内联定义不提供外部 函数的定义,并且不禁止外部 另一个翻译单元中的定义”

但是,当我在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

我认为源代码中函数

foo()
的定义是内联定义,因此汇编结果不应包含定义,就像我们使用原始内联声明它时一样,但似乎不是,为什么?
请注意,如果我们编译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 出现在前一个而不出现在后一个?

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

c gcc inline c99
1个回答
0
投票

在C++中,使用“static”关键字声明的函数称为静态函数。静态函数与类本身相关联,而不是与类的实例相关联。在类声明中定义静态函数时,编译器将其视为内联函数。 但是,当在类外部定义静态函数时,编译器会生成外部定义。这是因为静态函数可以在类中的任何位置调用,而不仅仅是在类的实例上。为了确保静态函数可以在程序中的任何地方访问,编译器需要在外部定义它们。

© www.soinside.com 2019 - 2024. All rights reserved.