int main() {
const int i =10;
int *j = const_cast<int*>(&i);
cout<<endl<<"address of i "<<&i;
cout<<endl<<"value of j "<<j;
(*j)++;
cout<<endl<<"value of *j "<<*j;
cout<<endl<<"value of i "<<i;
// If Not use Const //
int k = 10;
int *p = &k;
cout<<endl<<"address of k "<<&i;
cout<<endl<<"address of p "<<&p;
(*p)++;
cout<<endl<<"value of *p "<<*p;
cout<<endl<<"value of k "<<k<<endl;
}
输出是:
地址
i
0xbf8267d0
值j
0xbf8267d0
值*j
11
价值i
10
地址k
0xbf8267d0
地址p
0xbf8267c8
值*p
11
价值k
11
有人可以解释为什么在输出的第3和第4行
*j is 11
和i is 10
。
为什么i
也不是11?
答案 0 :(得分:6)
编译器可以假设在这种情况下的const变量不会被修改。它可以采取措施来生成更高效的代码。在您的示例中,i
被声明为const
,编译器将std::cout << i
替换为(有效)std::cout << 10
抛弃constness会导致未定义的行为,因此实际上不会发生任何事情。
考虑类似的事情
const int i = 5;
// ...
if (i > 10) { // impossible!
std::cout << "hello world!";
}
在上面,优化编译器可以在编译时确定常量5
可能大于10
,因此它将丢弃if检查和身体,如果你查看组件,你甚至不会看到"hello world!"
字符串,因为它会被优化掉并扔出去!即使您将...
替换为const_cast
并修改了i
的值,也没有更改允许编译器执行的优化,假设i
没有& #39; t改变。
答案 1 :(得分:4)
解释很简单:未定义的行为未定义。当您使用const_cast
抛弃实际声明为const
的对象的常量然后修改它时,程序展示未定义的行为,它可以做任何事情。它可以做你期望的,做你不期望的事情,它可以在线订购披萨。
在您的特定情况下,编译器可能会优化i
的所有用法,将其替换为文字10
(因为i
为const
,因此其值不可能永远以任何方式改变。)
与此同时,i
可能没有放在内存的只读部分(否则,您会在(*j)++
上崩溃),并且j
}是指向int
(而不是const int
)的指针,无法优化来自*j
的读数,因此实际存储在*j
中的值(即i
)已打印出来。
但以上只是猜测,真的。实际的原因可能是任何事情。具有未定义行为的程序是完全错误的,没有任何关于其行为的预测。