c-再次静态和外部

问题描述

我正在检查具有不同链接的声明中可能发生的各种情况,我有两个问题。

I。我有以下代码:

@Override
    public void onViewCreated(@NonNull final View view,@Nullable Bundle savedInstanceState) {
    RecyclerView recyclerView = findViewById(R.id.list);
    // recyclerView is not null now
}

可以与#include <stdio.h> static int a = 19; int main(void) { extern int a; { extern int a; printf("braces - %d\n",a); } printf("main - %d\n",a); } clang一起很好地编译,并且在两个gcc中都打印出19的相同结果。据我所知,根据标准6.2.2。,4),所有pritf都是a。我唯一不了解的是,为什么static的文件作用域a在主括号和大括号中可见?是否不应该按照脚注31隐藏文件范围?当我在其他文件中用不同的值定义另一个a时,两个a的输出仍为19。

II。现在,我执行以下操作:

printf

#include <stdio.h> static int a = 19; int main(void) { int a; //change in this line { extern int a; printf("braces - %d\n",a); } 大喊gcc,而variable previously declared ‘static’ redeclared ‘extern’正常运行并在主行中打印clang的{​​{1}} = 0(是,这是垃圾值),并且仍然大括号中的19个。
我猜a在这里适用6.2.2。 7),而a则没有。哪种解释是正确的,这里发生了什么?

我只能假设gcc大括号中的clang与主gcc中的a匹配,并且使其外部链接,然后看到它与文件范围a冲突。而且,为什么不让括号static a引用另一个文件中的a(脚注31?)?


事实上,即使我确实知道C ++与C有所不同(并且我询问C),我目前的理解实际上也接近here中接受的答案。

解决方法

我唯一不了解的是为什么文件作用域a 在主体和花括号中可见吗?

在文件范围中声明的变量a在main的块范围中可见

   static int a = 19;
         
   int main(void)
   {
      extern int a;
      //...

直到main中的声明重新在文件作用域中声明变量。因此main中的变量表示在文件范围中声明的相同变量。

在复合语句的块范围内

int main(void)
{
   extern int a;
   {
       extern int a;
       //...

在main封闭范围内的变量a的声明是可见的,直到在复合语句的块范围内的变量a的声明为止。因此,在compound语句中声明的变量表示与在函数main的封闭块范围中声明的变量相同。这三个变量都表示具有内部链接的相同变量。

然后根据C标准(6.2.2标识符链接)进行第二个程序

7如果在翻译单元中,相同的标识符出现在两个 内部和外部的联系,行为是不确定的

程序具有未定义的行为,因为在函数main的块作用域中声明了变量

static int a = 19;
     
int main(void)
{
    int a; 
    // ...

通过内部链接隐藏在文件范围中声明的变量。因此,根据C标准(6.2.2标识符的链接)

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

在复合语句的块作用域中声明的变量a具有外部链接。结果,翻译单元中的同一标识符具有外部和内部链接。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...