包含const_cast的代码片段的说明


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 11i is 10 .

为什么i也不是 11?

编译器可以假定在这种情况下不会修改 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不会更改(。

解释很简单:未定义的行为是未定义的。当你使用const_cast抛弃一个实际声明const对象的恒常性,然后修改它时,你的程序表现出未定义的行为,它几乎可以做任何事情。它可以做你所期望的事情,做你意想不到的事情,它可以在线订购披萨。

在你的特定情况下,编译器可能通过用文字10替换它来优化i的所有使用(因为iconst,所以它的值永远不会以任何方式改变(。

同时,i可能没有放在内存的只读部分(否则,你会在(*j)++上崩溃(,并且由于j是指向int(而不是const int(的指针,因此无法优化*j读取,因此实际存储在*j中的值(这是i的存储(被打印出来。

但以上只是猜测,真的。实际原因可能是任何事情。具有未定义行为的程序是完全错误的,无法预测其行为。

最新更新