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

标签 c gcc assembly objdump

我想知道为什么我们不能从函数外部访问函数内部声明的变量?从技术上讲,可以访问它们,因为它们就像全局/静态变量一样放入 .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命令编译并链接它:

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_n 放入 .data 段中,就像 global_static_nglobal_n 一样。如果我取消注释以下几行,我将收到错误:

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)

最佳答案

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

如果函数中的变量使用static,则该变量具有静态存储期限,但仅在函数内部可见,在函数外部不可见。

请注意,这种“可见性”仅限制编译器通过名称访问变量时。当然,函数可以返回或以其他方式公开静态变量的地址;然而,变量本身对于上述范围之外的编译器是不可见的。

关于c - 访问函数内部声明的静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43719804/

相关文章:

c++ - 这是什么类型的行为?

c - 为什么 va_arg() 在 x86_64 和 arm 上产生不同的效果?

assembly - OpenCL 在线编译:从 cl::program 或 cl::kernel 获取程序集

c - 如何在 C/C++ 中写入不同线程的堆栈?

assembly - 等效于其他架构上的 Z80 DJNZ 指令?

c - 一个网页请求中的多个 DNS 查询

c - Valgrind - 1 个 block 中的 2,064 个字节可能在丢失记录 57 of 64 中丢失

c - 如何用C语言使用VTK?

c++ - 如何隐藏链接器警告

c++ - 确定库的地址内存