关于const 的问题
网上看的:
我们仍然可以绕过编译器的限制
去修改被定义为“常量”的内存区域。看下面的代码:
const int i = 10;
// 这里 i 已经被定义为常量,
但是我们仍然可以通过另外的方式去修
改它的值。
// 这说明把 i 定义为常量,
实际上是防止通过 i 去修改所代表的内存。
int *pi = (int*) &i;
但通过实验我发现:
- C/C++ code
#include <iostream>#include <string>using namespace std;void func(const int *pi){ int *pp = (int *)pi; *pp = 100;}int main(){ const int a = 5; const int *pa = &a; cout<<"address:"<<&a << " value:"<< a << " address: "<< pa << " value: "<<*pa<< endl; func(pa); cout<<"address:"<<&a << " value:"<< a << " address: "<< pa << " value: "<<*pa<< endl; const int *pt = &a; cout << "address: "<< pt << " value: "<< *pt<< " "<< a<<endl; return 0;}输出:
address:0xbfabbe64 value:5 address: 0xbfabbe64 value: 5
address:0xbfabbe64 value:5 address: 0xbfabbe64 value: 100
address: 0xbfabbe64 value: 100 5
那么这个引用是新开辟的空间 ?
const int *pa = &a; ?
[解决办法]
不要纠结各种常量了,这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢!
[解决办法]
编译器对常量a的引用已经固化为5了
虽然内存中的数据已经改变,但是编译器使用a的时候还是认为它从来没变过,就是5
[解决办法]
不是这样理解的!
对于一个常量,通常编译器是不会去分配存储空间的,而是在代码中去做常量替代。也就是对于代码中所有的a,都替代成字面数字5。
而如果你对常量取地址,那么编译器才会被迫分配一个空间,里面最初也存放了5。但之后你用指针强制修改成了100。
所以程序输出的时候,凡是以a这个名字输出的,都是编译时就替换成5的这个字面值,凡是以指针输出的,都是取的实际内存中的值。
最后说一下,虽然可以这么修改常量,但对于C++来说这是未定义的代码行为,不同编译器可以做不同处理,并且不保证结果正确,也不一定会给出任何提示和警告!
[解决办法]
google"常量折叠"