有什么用声明一个函数内的静态变量为extern的? [英] What is the use of declaring a static variable as extern inside a function?

查看:133
本文介绍了有什么用声明一个函数内的静态变量为extern的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 的#include<&stdio.h中GT;静态I = 5;诠释的main()
{
EXTERN INT I;
的printf(%d个\\ N,I);
返回0;
}

能有人给任何用例来声明一个功能块内的静态变量为extern?


这是为什么不允许?

  INT的main()
{
静态I = 5;
EXTERN INT I;
的printf(%d个\\ N,I);
返回0;
}


解决方案

当你需要访问驻留在其他翻译单元中,没有全球露出外部变量的变量(有几个原因,比如名称冲突,这是有用的,或者该变量的不应该的直接访问,因此 静态 被用来限制其范围,但恩的头球仍然需要访问)。

作为一个例子,可以说我们有一个翻译单元 foo.c的,它包含:

  // foo.c的
静态INT I = 0;

I 不应改变或直接访问之外 foo.c的,但 foo.h中走来需要访问 I 为内联函数,但 I 不应该用 foo.h中接触到任何翻译单元,所以我们可以在功能层面使用的extern ,以

:仅在 INCI 的范围,内联函数需要使用揭露它

  // foo.h中
内嵌无效INCI(INT VAL)
{
    EXTERN INT I;
    我+ = VAL;
}


你的第二个例子是不允许的,因为编译器认为您要绑定两个不同的变量,以相同的符号名称,即:它在本地创建静态I 范围,但将搜索的extern INT I 在全局范围内,但没有找到它,因为静态I 作为在功能范围。一个更聪明的编译器将刚修好的联动到静态I ,这是否不遵循标准,我不知道。


现在我有一个 C类标准文档从工作(可耻的是我,我知道...),我们可以看到官方立场是什么(在C99):


  

标识符6.2.2关联


  
  

第3部分:


  
  

如果对象或函数的文件范围标识符的声明包含storageclass
  符静,标识符有内部连接。


  
  

第4节:


  
  

有关与存储类说明符的extern中声明的标识符
  一个范围,其中该标识符的先前声明是可见的,
  如果事先声明指定内部或外部联动,
  在后来的声明所述标识符的连接是相同的
  在事先声明中指定联动。如果没有事先声明
  可见,或者如果事先声明指定没有联系,则
  标识符有外部链接。


这样,因为静态会造成内部联动,的extern 将带来联动到目前的范围。还有一个脚注,这可能会导致变量隐藏:


  

23)如6.2.1规定,申报后可能会隐藏事先声明。


#include <stdio.h>

static i = 5;

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

Can someone give any use-case for declaring a static variable as extern inside a function block?

NEW: Why is this not allowed?

int main()
{
static i = 5;
extern int i;
printf("%d\n",i);
return 0;
}

解决方案

this is useful when you need to access a variable that resides within another translation unit, without exposing the external variable globally (for a few reasons, like name collision, or that the the variable shouldn't be directly accessed, so static was used to limit its scope, but that TU's header still needs access).

As an example, lets say we have a translation unit foo.c, it contains:

//foo.c
static int i = 0;

i shouldn't be changed or directly accessed outside foo.c, however, foo.h comes along requiring access to i for an inline function, but i shouldn't be exposed to any translation unit using foo.h, so we can use extern at functional level, to expose it only during the scope of IncI, the inline function requiring the use of i:

//foo.h
inline void IncI(int val)
{
    extern int i;
    i += val;
}


Your second example is 'disallowed' because the compiler thinks you are trying to bind two different variables to the same symbol name, ie: it creates the static i at local scope, but searches for the extern int i at global scope, but doesn't find it, because static i as at the function scope. a more clever compiler would just fix the linkage to the static i, whether or not this follows standards I wouldn't know.


Now that I have a C standards document to work from (shame on me I know...), we can see what the official stance is (in C99):

6.2.2 Linkages of identifiers

Section 3:

If the declaration of a file scope identifier for an object or a function contains the storageclass specifier static, the identifier has internal linkage.

Section 4:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, 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.

thus, because static will cause internal linkage, the extern will bring that linkage into the current scope. there is also a footnote stating that this may cause hiding of variables:

23) As specified in 6.2.1, the later declaration might hide the prior declaration.

这篇关于有什么用声明一个函数内的静态变量为extern的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆