c++ - 有关const_cast的一个疑惑?

浏览:44日期:2023-05-18

问题描述

描述你的问题pc是一个指向i的const指针,通过const_cast我们得到了一个普通的指针p。直接输出pc,p,以及&i,输出的都是003BF800,但是输出*pc,i却有1和32两种结果,那么请问在003BF800这个地址中存放的到底是整数1还是整数32,以及为什么会出现这种现象?

贴上相关代码

#include <iostream> using namespace std; int main() {

const int i = 32; const int *pc = &i; int *p = const_cast<int*>(pc); *p = 1; cout << *pc << ' ' << *p <<' '<<i<< endl; cout << pc << ' ' << p << ' ' << &i << endl; return 0;

}

贴上报错信息

贴上相关截图c++ - 有关const_cast的一个疑惑?

已经尝试过哪些方法仍然没解决(附上相关链接)

问题解答

回答1:

在003BF800中,保存的的确是整数1,由于p指针已改变了其值。然而缘何i的值为32,可能因为i是个编译时可计算的常量表达式'constexpr',在编译时已替换了相关内容。

回答2:

通过const_cast去除const限定符后获得的新变量,如果对应原始变量是非常量(nonconst)类型的,则可以更改新变量。如果原始变量是常量类型的,则更改新变量是未定义的行为。具体情况由编译器决定。

题主通过指针p改写原始变量i是未定义行为。

回答3:

这个没什么奇怪的,编译器知道i是常量,所以输出的时候直接用了立即数来输出,你改变了原来的值根本没有用。。。下面是g++ 4.8生成的汇编代码,一看便知。。

.LC0: .string ' ' .text .globl main .type main, @functionmain:.LFB1196: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 pushl %ebx andl $-16, %esp subl $32, %esp .cfi_offset 3, -12 movl $32, 20(%esp)// i leal 20(%esp), %eax movl %eax, 28(%esp) // pc movl 28(%esp), %eax movl %eax, 24(%esp) // p movl 24(%esp), %eax movl $1, (%eax) // *p = 1; movl 24(%esp), %eax movl (%eax), %ebx //值放到ebx备用 movl 28(%esp), %eaxmovl (%eax), %eax movl %eax, 4(%esp)//参数 *pc movl $_ZSt4cout, (%esp) //参数 cout call _ZNSolsEi movl $.LC0, 4(%esp) // '' movl %eax, (%esp) // cout call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc movl %ebx, 4(%esp) //*p movl %eax, (%esp) // cout call _ZNSolsEi movl $.LC0, 4(%esp) //'' movl %eax, (%esp) //cout call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc movl $32, 4(%esp) // !!! 编译器直接使用了立即数32,你改变原来的值没有用 movl %eax, (%esp) // cout call _ZNSolsEi movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)

相关文章: