首页 > 解决方案 > 在定义中使用静态关键字与在 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

有什么区别?

标签: cstaticdeclarationexternlinkage

解决方案


C 标准中的这句话显示了差异)6.2.2 标识符的链接)

5 如果函数标识符的声明没有存储类说明符,则它的链接将完全确定,就好像它是使用存储类说明符 extern 声明的一样。如果对象标识符的声明具有文件范围且没有存储类说明符,则其链接是外部的。

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

现在根据以下报价

4对于使用存储类说明符 extern 声明的标识符,在该标识符的先前声明可见的范围内,31) 如果先前声明指定内部或外部链接,则后面声明的标识符的链接是相同的作为先前声明中指定的链接。如果前面的声明不可见,或者前面的声明没有指定链接,则标识符具有外部链接

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

至于变量的标识符,那么

7 如果在翻译单元内,相同的标识符同时出现在内部和外部链接中,则行为未定义。

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


推荐阅读