【问题标题】:Shadowing of static global and local identifiers静态全局和本地标识符的阴影
【发布时间】:2014-04-02 22:37:34
【问题描述】:

以下程序在课堂上分发的练习工作表上。我们被要求提供它的输出,但根据我对链接的理解,file2.c 不应该有两个静态标识符 b 的实例,但程序编译时会发出警告并且运行良好。我的问题是,为什么允许这样做?我认为静态链接的目的是能够访问该文件中任何地方的标识符?

澄清:问题是关于 file2.c:有两个“静态 int b”声明。为什么允许?

/* 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 */

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); 

} 

提前感谢您的帮助(这是我第一次发帖,如果有格式错误,我深表歉意!)。

【问题讨论】:

    标签: c


    【解决方案1】:

    编译器会为每个全局静态变量创建一个不同的实例,即使您有多个名称相同的此类变量也是如此。

    事实上,编译器(或者可能是预处理器)会根据声明它的源文件的名称隐式更改每个此类变量的名称。

    您可以通过在头文件中声明一个全局静态变量来证明这一点,然后将此头文件包含在几个不同的源文件中。尝试在每个源文件中将其设置为不同的值,您会看到该变量在每个源文件中保留其不同的值。

    如果您想让一个全局变量的同一个实例可以在多个源文件中访问,那么您应该避免声明它static

    • 如果您在头文件中声明它,则使用extern 作为前缀,并在每个使用此变量的源文件中包含该头文件。
    • 如果您在源文件中声明它,则必须在每个使用此变量的其他源文件中将其声明为extern

    外部全局变量的地址仅在链接期间确定。这与以下情况形成对比,在这些情况下,变量的地址是在编译期间确定的:

    • 一个局部变量
    • 静态局部变量
    • 静态全局变量
    • 非外部全局变量

    我相信术语static linkage 是指在构建过程中将编译对象(或库)链接到可执行映像中,而不是dynamic linkage 指的是链接仅在运行时编译代码(也称为 DLL)到可执行映像中。


    更新:

    阅读您的说明后,我了解到唯一的问题是同名的局部变量和全局变量(static 属性对此问题没有区别)。

    在函数内部,局部变量总是“被编译器首选”而不是同名的全局变量。换句话说,在函数f 中,对变量b 的所有操作都应用于局部变量而不是全局变量。

    【讨论】:

    • @Nabla:很难确切地说出这个问题是关于什么的。据我了解,这是关于一个静态全局变量b,它在两个不同的文件中声明。
    • @barakmanos:谢谢你的回答!我对我的问题进行了编辑,以便更清楚。
    • @Nabla:是的,这就是我要问的。
    • @kero22:不客气,您可以通过点击旁边的 V 来接受答案(如果它回答了您的问题)。
    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    相关资源
    最近更新 更多