我试图详细了解静态和外部函数之间的区别.
我知道静态和外部内联函数之间的基本区别.
如果错误,请纠正我的理解:
下面是一个示例代码,我对此行为感到困惑.
在file1.c
#include <stdio.h>
#include "file.h"
int main(void)
{
fun1();
return 0;
}
static inline void fun1(void)
{
int i;
for (i = 0; i < 10; i++) {
static int k = 20;
printf("Value : %d \n", k++);
}
}
Run Code Online (Sandbox Code Playgroud)
file2.c中
#include <stdio.h>
inline void fun1(void)
{
int i;
int k = 0;
for (i = 0; i < 10; i++) {
printf("Value : %d \n", k++);
}
}
Run Code Online (Sandbox Code Playgroud)
file.h
#ifndef FILE_H
#define FILE_H
extern inline void fun1(void);
#endif
Run Code Online (Sandbox Code Playgroud)
当我编译上面的代码"gcc file1.c file2.c"时,从file2.c调用了fun1.这很明显,因为fun1被声明为extern,它应该采用file2.c中的extern函数(默认情况下所有内联函数都是extern?).
但是当我在file1.c中将静态内联函数更改为静态函数(static void fun1(void))时,从file1.c调用了fun1.可能是什么原因 ?
我还读到"如果内联函数声明了外部链接但未在同一翻译单元中定义,则行为未定义".但我不明白这一点.这可以用上面的例子来解释吗?
与C相比,C++中的静态和外部函数有什么区别吗?
extern您的代码不正确,因为您无法使用(默认情况下)声明函数并随后提供static定义。它能编译的事实并不表明有什么用处。
从n1548 \xc2\xa76.2.2:
\n\n\n\n\n如果在翻译单元内,相同的标识符同时出现在内部和外部链接中,则行为未定义。
\n
所以,你会得到这样的东西file1.c:
// Has external linkage (which is the default!)\nextern inline void fun1(void);\n\n// This would also have external linkage.\ninline void fun1(void);\n\n// This has static linkage.\nstatic inline void fun1(void) {\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n\n(注意:“外部链接”是默认值,但extern inline实际上意味着一些特殊的东西,它与 不同inline。)
嘭!未定义的行为。编译器甚至可能不会给您错误消息,尽管有些编译器似乎会为此提供错误消息。
\n\n\n错误: \'func\' 的静态声明遵循非静态声明\n\n\n
这个错误实际上与该函数是无关的inline。无论有或没有,这都是一个错误inline。
\n\n\n静态内联函数仅对定义它的翻译单元可见。
\n
所有函数都是如此static。它们具有“内部链接”,因此您可以将其放在static void func(void);一个文件中,而将完全不同的文件static int func(char *p);放在另一个文件中。这里没有inline区别。
\n\n\n外部内联函数可以在多个翻译单元中访问。
\n
是的,这就是为什么您不应该将它们放入头文件中。如果将它们放入头文件中,您将获得同一函数的多个不同定义,这些定义都可以从不同的翻译单元访问。这是一个错误。相反,将其放入extern inline源文件中,但它只需要是声明,而不是定义。
\n\n\n最好在头文件中定义内联函数
\n
在其他地方定义内联函数没有任何实际意义。如果您的函数仅在一个文件中使用,只需标记它static,编译器将决定如何调用该函数。
\n\n\n静态和静态内联函数定义之间没有区别。
\n
是的,没有区别。
\n\nstatic inline好吧,从技术上讲,不,这是有区别的,因为允许编译器以不同于函数的方式对待函数static。然而,现代编译器倾向于决定使用自己的一组规则来内联函数,并且函数是否内联inline并不会对该过程产生太大影响。
嗯,实际上还有另一个区别。如果不使用函数static inline定义,则不会在 GCC 中生成警告,但函数static会生成警告。这样您就可以将static inline函数放入头文件中。这是放入头文件的替代方法inline,头文件要求您extern inline在程序中的某个位置有一个用于该函数的函数。但是,如果编译器决定不内联您的static inline函数,或者因为它认为内联更糟糕,或者因为内联是不可能的,那么它必须在每个文件中制作该函数的单独副本。 s 用于.
static如果函数之前有非静态声明,则切勿声明该函数。即使编译通过,这也是一个错误。
不要inline extern在头文件中声明函数。这会为该函数创建一个“外部定义”,并且您在整个程序中只能拥有其中之一。
不要inline在头文件中声明函数而不定义它们。无关紧要。
以下是您想要执行此操作的方式:
\n\n在mylib.h:
// Provide "inline definition" of the function.\ninline int times_two(int x) {\n return x * 2;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n在mylib.c:
#include "mylib.h"\n\n// Provide "external definition" of the function.\nextern inline int times_two(int x);\nRun Code Online (Sandbox Code Playgroud)\n\n这是自 C99 以来的标准处理方式。编译器应该可以自由使用内部定义或外部定义,无论它认为哪一个更好。如果您没有外部定义或有多个外部定义,则可能会出现链接错误,就像常规函数一样。
\n\nC++ 对于内联函数有自己完全不同的规则。
\n