标签为 "常量" 的存档

全局常量和局部常量的区别

局部const

[root@IDC-D-2270 czt]# cat clzd.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
    const int a = 10;
    int *p = (int *) &a;
    cout << *p << " " << a << endl;
    cout << p << " " << &p << endl;
    *p = 20;
    cout << *p << " " << a << endl;
    cout << p << " " << &p << endl;
    return 0;
}
[root@IDC-D-2270 czt]# g++ clzd.cpp
[root@IDC-D-2270 czt]# ./a.out
10 10
0x7fff93f7736c 0x7fff93f77360
20 10
0x7fff93f7736c 0x7fff93f77360

神奇的事情发生了,const内容被通过指针改动,而且同一空间的内容竟然不同
首先,局部const虽然看上去与全局常量没有什么区别,但编译器在编译时会在栈区为其分配存储空间,所以局部const称作“只读”变量更为恰当。
其次,常量在编译时默认遇到取地址时会为其分配地址
所以这里修改的只是这个副本而本身并未改变
这是编译器优化的结果。被称作常量折叠const folding

全局const

[root@IDC-D-2270 czt]# cat clzd.cpp
#include <iostream>
using namespace std;
const int a = 10;
int main(int argc, char **argv) {
    int *p = (int *) &a;
    cout << *p << " " << a << endl;
    cout << p << " " << &p << endl;
    *p = 20;
    cout << *p << " " << a << endl;
    cout << p << " " << &p << endl;
    return 0;
}
[root@IDC-D-2270 czt]# g++ clzd.cpp
[root@IDC-D-2270 czt]# ./a.out
10 10
0x400b0c 0x7fffd7e4ae78
Segmentation fault

这里会发现,全局const在同样企图通过指针修改其值时会出现段错误,也就是说const全局常量存储空间在常量存储区段上分配,这才是纯粹的只读的常量,所以当企图通过指针修改常量存储区段上的数据时会出现段错误。当然世事无绝对,通过非常手段还是可以修改常量区段的。
阅读更多…