简体   繁体   English

静态全局和本地标识符的阴影

[英]Shadowing of static global and local identifiers

The following program was on a practice worksheet given out in class. 以下程序是在课堂上给出的练习工作表上。 We are asked to give its output, but from what I understand about linkage, file2.c should not have two instances of the static identifier b but the program compiles with a warning and runs just fine. 我们被要求提供它的输出,但是根据我对链接的理解,file2.c不应该有两个静态标识符b的实例,但是程序会编译一个警告并运行得很好。 My question is, why is this allowed? 我的问题是,为什么允许这样做? I thought the point of static linkage was to be able to access an identifier everywhere in that file? 我认为静态链接的目的是能够在该文件中的任何位置访问标识符?

CLARIFICATION: The question is about file2.c: there are two "static int b" declarations. 澄清:问题是关于file2.c:有两个“static int b”声明。 Why is that allowed? 为什么允许这样做?

/* file1.c */ / * file1.c * /

#include <stdio.h> 

extern int a; 
static int b; 

void f(int); 
void g(void); 

int main() { 

  a = 10; 
  b = 20; 
  f(a); 
  f(b); 
  g(); 
  printf("main: %d %d\n", a, b); 

  return 0; 
} 

/* file2.c */ / * file2.c * /

include <stdio.h> 

int a; 
static int b; 

void f(int c) { 
  static int b = 5; 

  a += b; 
  b += c; 
  printf("f: %d %d\n", a , b ) ; 

} 

void g(void) { 
  a += 5; 
  b = 10; 
  printf("g: %d %d\n", a , b); 

} 

Thank you in advance for any help (this is my first time posting so I apologize if there are formatting errors!). 提前感谢您的帮助(这是我第一次发帖,所以如果有格式错误我会道歉!)。

The compiler creates a different instance for every global static variable, even when you have several such variables with identical names. 编译器为每个全局静态变量创建一个不同的实例,即使您有多个具有相同名称的变量也是如此。

In fact, the compiler (or possibly, the preprocessor) implicitly changes the name of every such variable, according to the name of the source file which declares it. 实际上,编译器(或可能是预处理器)根据声明它的源文件的名称隐式地更改每个这样的变量的名称。

You can prove this to yourself by declaring a global static variable in a header file, and then include this header file in several different source files. 您可以通过在头文件中声明全局静态变量来证明这一点,然后将此头文件包含在几个不同的源文件中。 Try to set it to a different value in each source file, and you'll see that this variable retains its different value in each source file. 尝试在每个源文件中将其设置为不同的值,您将看到此变量在每个源文件中保留其不同的值。

If you want to have the same instance of a global variable accessible in several source files, then you should refrain from declaring it static : 如果要在多个源文件中访问全局变量的相同实例 ,则应避免将其声明为static

  • If you declare it in a header file, then use extern as prefix, and include the header file in every source file that makes use of this variable. 如果在头文件中声明它,则使用extern作为前缀,并在每个使用此变量的源文件中包含头文件。
  • If you declare it in a source file, then you will have to declare it as extern in every other source file that makes use of this variable. 如果在源文件中声明它,则必须在使用此变量的每个其他源文件中将其声明为extern

The address of an external global variable is determined only during linkage . 外部全局变量的地址仅在链接期间确定。 This is in contrast with the following cases, in which the address of the variable is determined during compilation : 这与以下情况形成对比,其中在编译期间确定变量的地址:

  • A local variable 一个局部变量
  • A static local variable 一个静态局部变量
  • A static global variable 一个静态全局变量
  • A non-external global variable 非外部全局变量

I believe that the term static linkage refers to the linkage of compiled objects (or libraries) into the executable image during the build process , as opposed to dynamic linkage which refers to the linkage of compiled code (also known as DLL) into the executable image only during runtime . 我认为术语static linkage是指在构建过程中将编译对象(或库)链接到可执行映像,而不是dynamic linkage ,它指的是已编译代码(也称为DLL)与可执行映像的链接仅在运行期间


UPDATE: 更新:

After reading your clarification, I understand that the only issue is with a local variable and a global variable of the same name (the static attribute makes no difference with regards to this issue). 在阅读了您的澄清之后,我理解唯一的问题是局部变量和同名的全局变量( static属性对此问题没有任何影响)。

Inside a function, a local variable is always "preferred by the compiler" over a global variable with the same name. 在函数内部,对于具有相同名称的全局变量,局部变量始终是“编译器首选”。 In other words, in function f , all operations on variable b are applied on the local variable and not on the global variable. 换句话说,在函数f ,对变量b所有操作都应用于局部变量而不是全局变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM