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

标签 c static declaration extern linkage

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

#include <stdio.h>

static int a();

int a(){
 return 5;
}

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

作为旁注,与上述相同的行为发生在内联函数中,即只有声明可以具有关键字。

但是,以下操作失败,但对变量执行相同操作:

#include <stdio.h>

static int a;

int a = 5;

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

出现错误: “a”的非静态声明位于静态声明之后

有什么区别?

最佳答案

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.

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

关于c - 在定义中使用 static 关键字与在 C 中使用声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62379166/

相关文章:

计算 int 中的位数 - 为什么这段代码有效?

c++ - C中1的稀疏矩阵的快速矩阵乘法

c++ - .cpp 文件头部的静态语句未调用

c# - 哪个用于 C# : static, const 中的算法参数,只读?

C++/C++11 使用初始化列表初始化对象的静态数组/vector 的有效方法,并支持基于范围的

C - 为全局变量显式编写 extern 关键字

c - Linux中所有的挂载点存放在哪里

c - 将输入从标准输入传递到函数时进行缓冲

python - 在 `__init__()` 之外声明的实例变量在 python 中有什么区别吗?

python - 将包的 __init__.py 模块用于通用抽象类是 pythonic 吗?