访问在函数内部声明的静态变量

accesing static variables that declared inside functions

我想知道为什么我们不能从函数外部访问函数内部声明的变量?技术上可以访问它们,因为它们像 global/static 变量一样放入 .data 段。还有全局变量和静态全局变量有什么区别?

我有一个 C 文件如下:

int global_n =1;
static int global_static_n=2;

int main(){
    int local_n=3;
    static int local_static_n=4;
    return 0;
}

void test(){
    global_n=9;
    global_static_n=8;
    //local_n=7;
    //local_static_n=6;
}

我通过以下 GCC 命令编译并 link 它:

gcc -Wall -m32 -nostdlib main.c -o main.o

我通过以下 OBJDUMP 命令反汇编它:

objdump -w -j .text -D -Mi386,addr32,data32,intel main.o
objdump -w -s -j .data main.o

并获取以下转储:

    Disassembly of section .text:

080480f8 <main>:
 80480f8:   55                      push   ebp
 80480f9:   89 e5                   mov    ebp,esp
 80480fb:   83 ec 10                sub    esp,0x10
 80480fe:   c7 45 fc 03 00 00 00    mov    DWORD PTR [ebp-0x4],0x3
 8048105:   b8 00 00 00 00          mov    eax,0x0
 804810a:   c9                      leave  
 804810b:   c3                      ret    

0804810c <test>:
 804810c:   55                      push   ebp
 804810d:   89 e5                   mov    ebp,esp
 804810f:   c7 05 00 a0 04 08 09 00 00 00   mov    DWORD PTR ds:0x804a000,0x9
 8048119:   c7 05 04 a0 04 08 08 00 00 00   mov    DWORD PTR ds:0x804a004,0x8
 8048123:   90                      nop
 8048124:   5d                      pop    ebp
 8048125:   c3 


Contents of section .data:

804a000 01000000 02000000 04000000

我可以看到 local_static_nglobal_static_nglobal_n 一样放入 .data 段。如果我取消注释以下行,我将得到错误:

local_n=7;
local_static_n=6;
error: ‘local_n’ undeclared (first use in this function)
error: ‘local_static_n’ undeclared (first use in this function)

静态变量只能在声明的范围内访问。但是,如果您确实需要访问它们:

#include <stdio.h>

int global_n =1;
static int global_static_n=2;

void test(int* pStatic);

int main(){
    int local_n=3;
    static int local_static_n=4;
    printf("local static %d\n",local_static_n);
    test(&local_static_n);
    printf("local static %d\n",local_static_n);
    return 0;
}

void test(int* pStatic){
    *pStatic=5;
    global_n=9;
    global_static_n=8;
    //local_n=7;
    //local_static_n=6;
}

但是,不推荐这样做。如果你想访问静态变量,你可能应该将数据存储在不同的范围内,在你的函数和其他代码可以访问它的地方。

如果在命名空间范围内使用 static(即在函数和 类 之外),则相应的变量仅对该翻译单元可见,而不对其他翻译单元可见。此构造用于避免在不同翻译单元/库中定义的全局变量的意外名称冲突。这被称为 "internal linkage"

如果static用于函数中的变量,则此变量具有静态存储持续时间,但仅在函数内部可见,在外部不可见。

请注意,此 "visibility" 只是在通过名称访问变量时限制编译器。当然,函数可以 return 或以其他方式公开 static 变量的地址;但是变量本身对上述范围之外的编译器不可见。

I want to know why we can't access variables those declared inside functions from outside the function? It's technically possible to access them since they put in .data segment just like global/static variables.

让它按您希望的方式工作没有技术问题。然而,专门设计 C 语言的人并不希望它以这种方式工作。这些限制是故意的。

信息隐藏是一种通过显式限制对某些数据的访问来简化程序推理的技术。这是如何做到这一点的一个例子。