如果函数声明不在头文件(.h)中,而是仅在源文件(.c)中,为什么需要使用 static 关键字?当然,如果你只在.c文件中声明它,那么其他文件就不会看到它,因为你不应该#include .c文件,对吧?
答案 0 :(得分:5)
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
时,编译器确切地知道程序的哪些部分调用它以及使用什么参数,因此它可以执行常量折叠,死代码消除和/或内联。
答案 1 :(得分:4)
static
关键字会降低函数对文件范围的可见性。这意味着您无法在其他单元中本地声明该函数并使用它,因为链接器不会将其添加到全局符号表中。这也意味着您也可以在其他单位中使用该名称(每个文件中可能有static void testOutput();
,如果省略static
则无法使用{。}}。
根据经验,您应该尽可能保持符号的可见性。因此,如果您不需要外部例程(并且它不是某个界面的一部分),请保留static
。
答案 2 :(得分:2)
它允许您在不同的源文件中具有相同名称的函数,因为编译器会为每个静态函数的名称添加一个隐式前缀(基于函数所在文件的名称),从而防止多重定义链接错误。
帮助维护代码的人知道该函数不作为接口的一部分公开,并且仅在文件内部使用(非静态函数可用于其他源文件即使,如果未使用extern
关键字在任何标头文件中声明。