在同一函数中定义变量及其静态等价物

Xat*_*ian 17 c c++ static scope shadowing

我不明白以下代码是如何工作的:

#include "stdio.h"

int main(void) {
  int i = 3;
  while(i--) {
    static int i = 100;
    i--,
    printf("%d\n", i);
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用Clang或GCC编译的代码打印以下输出:

99
98
97
Run Code Online (Sandbox Code Playgroud)

有人能解释一下这里发生了什么吗?看起来在一条指令中实现了两次操作并且不止一次.是不确定的行为?我在C++中观察到相同的行为.

Pra*_*ari 24

这不是未定义的行为.

#include "stdio.h"

int main(void) {
  int i = 3; //first i
  while(i--) {
    static int i = 100; //second i
    i--,
    printf("%d\n", i);
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在while循环体中,大多数局部i(第二i)是优选的.在while循环中检查条件时,它不知道身体中有什么.所以先选择没问题i.

  • 只是一个信息.. static int i = 100; 只执行一次..如果不是静态结果将是99,99,99 (8认同)
  • @Sreeragh AR:这是误导.在C和C++中,`i`初始化*静态*(又名"在编译时").它甚至从未真正执行过一次.C语言甚至没有"执行"静态对象初始化的概念.即使初始化程序似乎写在函数内部,实际的初始化也发生在它的边界之外. (2认同)

use*_*738 11

维基百科对此非常突出:

在计算机编程中,当在特定范围内声明的变量(决策块,方法或内部类)与在外部范围中声明的变量具有相同的名称时,会发生变量阴影.在标识符(名称而不是变量)的级别上,这称为名称屏蔽.该外部变量被称为由内部变量遮蔽,而内部标识符被称为掩盖外部标识符.

现在在块内部,它找到静态变量并对其进行处理,但while条件递减,i这是在块外声明的那个.范围不同 - 使用正确的值是没有问题的i.这是合法的C代码,但不一定是写东西的好方法.

其实这样做gcc -Wshadow progname.c

progname.c: In function 'main':
progname.c:7:20: warning: declaration of 'i' shadows a previous local [-Wshadow]
         static int i=2;
                    ^
progname.c:5:9: warning: shadowed declaration is here [-Wshadow]
     int i=2;
         ^
Run Code Online (Sandbox Code Playgroud)

从标准§6.2.1p4开始

...如果标识符指定同一名称空间中的两个不同实体,则范围可能会重叠.如果是这样,一个实体(内部范围)的范围将严格地在另一个实体(外部范围)的范围之前结束.在内部范围内,标识符指定在内部范围内声明的实体; 在外部作用域中声明的实体在内部作用域内是隐藏的(并且不可见).