我想知道为什么我们无法从函数外部访问那些在函数内部声明的变量?它在技术上可以访问它们,因为它们像全局/静态变量一样放入.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_n
和global_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)
答案 0 :(得分:3)
如果在命名空间作用域中使用static
(即在函数和类之外),则相应的变量仅对此转换单元可见,而对于其他转换单元则不可见。此构造用于避免在不同翻译单元/库中定义的全局变量的无意名称冲突。这被称为“内部联系”
如果static
用于函数中的变量,则此变量具有静态存储持续时间,但它仅在函数内部可见,而不在外部。
请注意,此“可见性”仅限制编译器在通过其名称访问变量时。当然,函数可以以其他方式返回或以其他方式公开static
变量的地址;但是变量本身对于上述范围之外的编译器是不可见的。
答案 1 :(得分:1)
我想知道为什么我们不能从函数外部访问那些在函数内部声明的变量?技术上可以访问它们,因为它们像全局/静态变量一样放入.data段。
使其按照您希望的方式工作没有任何技术问题。然而,设计C语言的人特别不希望它以这种方式工作。这些限制是有目的的。
信息隐藏是一种通过明确限制对某些数据的访问来更容易推理程序的技术。这是如何做到这一点的一个例子。
答案 2 :(得分:0)
静态变量只能在声明的范围内访问。但是,如果您确实需要访问它们:
#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;
}
但是,不建议这样做。如果要访问静态变量,您可能应该将数据存储在不同的范围内,您的函数和其他代码可以访问它。