C语言 为什么extern不能链接到静态变量?

pb3skfrl  于 5个月前  发布在  其他
关注(0)|答案(5)|浏览(81)

为什么extern int n在声明n时不能编译(在不同的文件中)static int n,但在声明int n时可以编译?(这两个声明都在文件范围内)。
基本上,为什么文件作用域中的int n和同一作用域中的static int n不一样?它只和extern有关吗?如果是,我遗漏了extern什么?

4dbbbstv

4dbbbstv1#

static的全部和全部目的是声明一个变量对于它在中声明的源文件是私有的。因此,它正在做的正是防止外部连接的工作。
请记住,有四种类型的文件作用域变量定义:

  1. int blah = 0;- blah在此文件中定义,可从其他文件访问。其他文件中的定义重复,会导致错误。
  2. extern int blah;- blah必须在其他地方定义,并从该文件引用。
  3. int blah;-这是FORTRAN COMMON的道德等价物。您可以在文件中拥有任何数量的这些文件,并且它们都被链接器解析为一个共享int。(*)
  4. static int blah;(可选的初始化器)-这是静态的。它对这个文件是完全私有的。它在其他文件中是不可见的,你可以有许多不同的文件都声明static TYPE blah;,它们都是不同的
    对于观众中的纯粹主义者:'文件' = * 编译单元
    请注意,函数内部的静态(不在文件范围内)的作用域更严格:如果两个函数在同一个文件中声明static int bleh = 0;,则它们是不相关的。
    ):对于那些不熟悉的人,在通常的模式中,一个编译单元必须定义一个全局变量,其他编译单元可以引用它。它“生活”在那个编译单元中。在上面的情况(3)中,没有文件如果两个文件都是int blah = 0;,如果两个文件都是int blah;,那么链接器会很高兴地创建一个全局的int,并使所有的代码都引用它。
bogh5gae

bogh5gae2#

在标准C语言中,在函数外部声明的变量有两个作用域。extern声明表示变量的位置还不知道,但将由链接器整理出来;它与非静态变量兼容,但extern static只是一个疯狂的说法!
当然,在实践中,现在还有其他的变量。特别是,现在在单个源文件和整个程序之间有了作用域级别;单个共享库的级别是一个有用的级别(可以通过GCC函数属性等机制设置)。但这只是非静态变量主题的一个变体; static保持了以前的解释。

t1qtbnec

t1qtbnec3#

根据MSDN文档:
修改变量时,static关键字指定变量具有静态持续时间(它在程序开始时被分配,在程序结束时被释放)并将其设置为0,除非指定了另一个值。当在文件范围内修改变量或函数时,static关键字指定变量或函数具有内部链接(其名称在声明它的文件外部不可见)。
Static (C++) on MSDN:互联网档案馆的存档,存档日期2015年1月;另请参阅最新文档:static §存储类(C++)|Microsoft Windows

8hhllhi2

8hhllhi24#

iv.c:2:1:错误:声明说明符中有多个存储类extern static int i; ^
这就是我们试图extern一个静态变量时得到的结果。声明extern static int i; -类似于声明float int i;你不能让float和int出现在同一个声明中,对吗?同样,你不能在同一个声明中有extern和static。

qyuhtwio

qyuhtwio5#

顺便说一句。这是一些法律的C程序:

static int ok;
extern int ok;

int
main(void)
{
}

字符串
但这是违法的:

extern int error;
static int error;

int
main(void)
{
}

相关问题