您的代码不正确,因为您无法使用以下方式声明函数extern
(这是默认的)然后提供一个static
定义。它能编译的事实并不表明有什么用处。
从 n1548 §6.2.2 开始:
如果在翻译单元内,相同的标识符同时出现在内部和外部链接中,则行为未定义。
所以,你会得到这样的东西file1.c
:
// Has external linkage (which is the default!)
extern inline void fun1(void);
// This would also have external linkage.
inline void fun1(void);
// This has static linkage.
static inline void fun1(void) {
...
}
(注:“外部链接”是默认值,但extern inline
实际上意味着一些特殊的东西,它不同于inline
.)
嘭!未定义的行为。编译器甚至可能不会给您错误消息,尽管有些编译器似乎会为此提供错误消息。
error: static declaration of 'func' follows non-static declaration
这个错误实际上有nothing与该功能有关inline
。无论有或没有,这都是一个错误inline
.
那些问题呢?
静态内联函数仅对定义它的翻译单元可见。
这对所有人都是如此static
功能。他们有“内部联系”,所以你可以static void func(void);
在一个文件和一个完全不同的文件中static int func(char *p);
在不同的文件中。这inline
这里没有区别。
外部内联函数可以在多个翻译单元中访问。
是的,这就是为什么你不应该将它们放在头文件中。如果将它们放入头文件中,您将获得同一函数的多个不同定义,这些定义都可以从不同的翻译单元访问。这是一个错误。相反,将extern inline
在源文件中,但它只需要是声明,而不是定义。
最好在头文件中定义内联函数
在其他地方定义内联函数没有任何实际意义。如果您的函数仅在一个文件中使用,只需标记它static
编译器将决定如何调用该函数。
静态和静态内联函数定义之间没有区别。
是的,没有区别。
嗯,从技术上来说,不,是有区别的,因为编译器可以处理static inline
功能与仅不同static
功能。然而,现代编译器倾向于决定使用自己的一组规则来内联函数,以及函数是否是inline
不会对这个过程产生太大影响。
嗯,实际上还有另一个区别。 Astatic inline
如果不使用函数定义,则不会在 GCC 中生成警告,但是static
函数将.这样你就可以放一个static inline
头文件中的函数。这是放置的替代方法inline
在头文件中,这需要你有一个extern inline
在你的程序中的某个地方使用这个函数。但是,如果编译器决定不内联您的static inline
函数,要么是因为它认为内联更糟糕,要么是因为内联是不可能的,那么它必须在使用该函数的每个文件中制作该函数的单独副本。
那么,如何正确地做到这一点呢?
永远不要声明函数static
如果它有一个先前的非静态声明。即使编译通过,这也是一个错误。
不要声明inline extern
头文件中的函数。这会为该函数创建一个“外部定义”,并且您在整个程序中只能拥有其中之一。
不声明inline
头文件中的函数而不定义它们。无关紧要。
以下是您想要执行此操作的方式:
In mylib.h
:
// Provide "inline definition" of the function.
inline int times_two(int x) {
return x * 2;
}
In mylib.c
:
#include "mylib.h"
// Provide "external definition" of the function.
extern inline int times_two(int x);
这是自 C99 以来的标准处理方式。编译器应该可以自由地使用内部定义或外部定义,无论它认为哪一个更好。如果您没有外部定义或有多个外部定义,则可能会出现链接错误,就像常规函数一样。
C++ 对于内联函数有自己完全不同的规则。