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;
}产出如下:
i0xbf8267d0地址j0xbf8267d0的值*j11值i10值k0xbf8267d0地址p0xbf8267c8地址*p11值k11值
有谁能解释一下为什么在第三行和第四行
*j is 11和i is 10.
为什么i也不是11呢?
发布于 2015-10-16 07:34:29
解释很简单:未定义的行为是未定义的。当您使用const_cast丢弃一个实际上声明为const的对象的常数,然后对其进行修改时,您的程序就会显示出未定义的行为,它几乎可以做任何事情。它可以做你想做的事,做你不想做的事,它可以在线订购披萨。
在您的特殊情况下,编译器可能通过用文字i替换它来优化它的所有用法(因为i是const,所以它的值永远不会以任何方式改变)。
同时,i可能没有放在内存的只读部分(否则,会在(*j)++上崩溃),而且由于j是指向int的指针(而不是指向const int),因此无法优化*j的读取,因此实际存储在*j中的值(即i的存储)将被打印出来。
但以上只是猜测,真的。真正的原因可能是什么。一个行为不明确的程序是错误的,它的行为是无法预测的。
发布于 2015-10-16 07:30:18
编译器可以假设在这种情况下不会修改const变量。它可以采取步骤来生成更高效的代码。在您的示例中,由于i被声明为const,编译器将std::cout << i替换为(实际上) std::cout << 10
抛弃恒常会导致未定义的行为,因此没有任何事情是可以保证的。
考虑一下类似的事情
const int i = 5;
// ...
if (i > 10) { // impossible!
std::cout << "hello world!";
}在上面,优化编译器可以在编译时发现常量5不可能大于10,因此它将删除if检查和正文,如果您查看程序集,您甚至不会看到"hello world!"字符串,因为它已经被优化并丢弃了!即使您用一个...替换了const_cast,并且修改了i的值,这不会改变编译器可以执行的优化,前提是i不会改变。
https://stackoverflow.com/questions/33164790
复制相似问题