旧事重提——const变量的存储区及修改权限

最近突然想起hjbolide在论坛上发过的这篇帖子:http://www.jluopen.org/bbs/viewthread.php ?tid=129
在帖子的最后,有这么一个很有趣的实验:


    const int a = 1;     int *p = const_cast<int*>(&a);     *p = 2;     cout << “value a=”<< a << endl;     cout << “value *p=” <<*p << endl;     cout << “address a=” <<&a << endl;     cout << “address p=” <<p << endl;

const变量居然被合法的修改了!
这里说说我最近的想法:
const变量有全局的和局部的,C语言中全局的const变量默认为外连接,所以默认都是有内存地址的,c++中全局的const变量默认为内连接,它可以被编译 器放到符号表中作为编译期常量,所以在c中,const int k = 2; int a[k]是非法的,但在c++中是合法的。
这是全局const变量,局部的const变量在C和C++中一视同仁,都是放在函数局部栈中的,把编译后的可执行文件在汇编级调试一下马上就能看出来。
这样,问题就很明了。在c和c++中,局部的const变量只是用来吓唬人的,想改它的值照样改,因为它存在于函数局部栈中,根本就不受任何权限的保护。当然修改的时候只要做个强制类型转化就好。
至于全局的const变量,C中默认是外连接,它有地址,有地址当然也能够被改掉,所以,你可以像在C语言中改变局部const变量那样通过指针来修改全 局const的值,编译时没有任何问题,连个warning都没有,只不过在运行时,你会得到一个segmentation fault而已。为什么呢?因为全局的const变量是存放在只读数据段里的,它比函数局部栈里的那些const变量高级,它受到只读数据段的权限保护, 所以,你试图修改一个只读数据段中的内容,会得到一个运行时错误。

你可能感兴趣的:(c,汇编,存储,语言,编译器)