C语言中的“静态”函数是什么?
让我们从头说起。
这一切都是基于一个叫做“联动”的东西:
在不同作用域中声明的标识符或在同一作用域中声明的标识符可以通过称为链接的进程引用相同的对象或函数。29)有三种联系:外部联系、内部联系和无联系。”
来源:C18, 6.2.2/1
在构成整个程序的翻译单元和库的集合中,带有外部链接的特定标识符的每个声明都表示相同的对象或函数。在一个翻译单元中,带有内部链接的标识符的每个声明都表示相同的对象或函数。没有链接的标识符的每个声明都表示一个唯一的实体。”
来源:C18, 6.2.2/2
如果函数定义时没有存储类说明符,则默认情况下函数具有外部链接:
如果函数的标识符声明没有存储类说明符,则确定其链接的方法与使用存储类说明符extern声明时完全相同。
来源:C18, 6.2.2/5
这意味着,如果程序包含多个翻译单元/源文件(.c或.cpp),则该函数在程序的所有翻译单元/源文件中都可见。
在某些情况下,这可能是个问题。如果你想使用f.e.两个不同的函数(定义),但在两个不同的上下文中(实际上是文件-上下文)使用相同的函数名,该怎么办?
在C和c++中,静态存储类限定符应用于文件范围内的函数(在c++中不是类的静态成员函数或另一个块中的函数)现在可以提供帮助,并表示相应的函数只在定义它的翻译单元/源文件中可见,而在其他tlu /文件中不可见。
如果对象或函数的文件作用域标识符声明中包含存储类说明符static,则该标识符具有内部链接。30)”
函数声明只有在文件范围内才可以包含存储类说明符静态;6.7.1见。
来源:C18, 6.2.2/3
因此,静态函数只有在以下情况下才有意义:
您的程序包含几个翻译单元/源文件(.c或.cpp)。
and
您希望将函数的作用域限制在定义特定函数的文件中。
如果这两个需求不匹配,就不需要考虑将函数限定为静态函数。
边注:
正如前面提到的,静态函数在C和c++之间没有任何区别,因为这是c++从C继承来的特性。
在c++社区中,有一场令人心碎的争论是,与使用未命名的名称空间相比,将合格函数降级为静态函数并不重要。未命名的名称空间最初是由c++ 03标准中一个错误的段落初始化的,宣布静态函数的使用已弃用,很快委员会自己就对其进行了修订,并在c++ 11中删除了。
这涉及到各种SO问题:
未命名/匿名名称空间vs.静态函数
未命名命名空间相对于静态命名空间的优越性?
为什么未命名的名称空间是静态名称空间的“高级”替代品?
弃用静态关键字…没有更多的?
事实上,根据c++标准,它还没有被弃用。因此,使用静态函数仍然是合法的。即使未命名的命名空间有优势,关于在c++中使用或不使用静态函数的讨论也取决于一个人的想法(基于意见),这并不适合本网站。