在内联说明符的 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()
的定义是内联定义,因此汇编结果不应包含定义,就像我们使用原始内联声明它时一样,但似乎不是,为什么?
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++中,使用“static”关键字声明的函数称为静态函数。静态函数与类本身相关联,而不是与类的实例相关联。在类声明中定义静态函数时,编译器将其视为内联函数。 但是,当在类外部定义静态函数时,编译器会生成外部定义。这是因为静态函数可以在类中的任何位置调用,而不仅仅是在类的实例上。为了确保静态函数可以在程序中的任何地方访问,编译器需要在外部定义它们。