如果函数声明不在头文件(.h)中,而是仅在源文件(.c)中,为什么需要使用static关键字?当然,如果你只在.c文件中声明它,那么其他文件就不会看到它,因为你不应该#include .c文件,对吧?
static
所做的是使得无法通过头文件声明和调用其他模块中的函数。
回想一下,C中的头文件包含只是文本替换:
// bar.c
#include "header.h"
int bar()
{
return foo() + foo();
}
// header.h
int foo(void);
得到预处理成为
int foo(void);
int bar()
{
return foo() + foo();
}
事实上,你可以取消header.h
,并且首先以这种方式写bar.c
。同样,foo
的定义在任何一种情况下都不需要包含标题;包括它只是添加一个检查,foo
的定义和声明是一致的。
但是如果你要将foo
的实现改为
static int foo()
{
// whatever
return 42;
}
然后foo
的声明将停止工作,在模块和头文件中(因为头文件只是被替换为模块)。或者实际上,声明仍然“有效”,但它停止引用你的foo
函数,当你试图调用foo
时链接器会抱怨它。
使用static
的主要原因是为了防止链接器冲突:即使foo
和bar
在同一个模块中,并且在模块之外没有任何东西称为foo
,如果它不是static
,它仍然会与任何其他非static
函数foo
冲突。第二个原因是优化:当函数是static
时,编译器确切地知道程序的哪些部分调用它以及使用什么参数,因此它可以执行常量折叠,死代码消除和/或内联。
static
关键字将函数的可见性降低到文件范围。这意味着您无法在其他单元中本地声明该函数并使用它,因为链接器不会将其添加到全局符号表中。这也意味着您也可以在其他单位中使用该名称(您可能在每个文件中都有一个static void testOutput();
,如果省略static
,这是不可能的。)
根据经验,您应该尽可能地保持符号的可见性。因此,如果你不需要外面的例程(并且它不是某个接口的一部分),那么保持它static
。
extern
关键字)。