在定义中使用 static 关键字与在 C 中声明

Using static keyword in definition vs declaration in C

以下编译正常,仅在函数声明期间使用 static

#include <stdio.h>

static int a();

int a(){
 return 5;
}

int main(){
 printf("%d\n", a());
 return 0;
}

附带说明,inline 函数会发生与上述相同的行为,即只有声明可以包含关键字。

但是以下失败了,但在变量上做同样的事情:

#include <stdio.h>

static int a;

int a = 5;

int main(){
 printf("%d\n", a);
 return 0;
}

出现错误: non-static declaration of 'a' follows static declaration.

有什么区别?

C 标准中的引用显示了差异)6.2.2 标识符的链接)

5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

所以一个函数看起来像是具有隐式存储说明符 extern(但这并不意味着它具有与在本例中具有外部链接的对象标识符相反的外部链接)。

现在根据下面的报价

4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage

因此该函数具有内部链接,因为它的初始声明带有存储说明符 static。

至于一个变量的标识符则

7 If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

以上引述的简历如下。如果函数没有显式指定存储 class 说明符 extern,则其链接由先前的函数声明确定(如果存在此类声明)。至于对象的标识符,那么在这种情况下它具有外部链接。如果事先声明了带有内部链接的标识符,则行为未定义。