const 疑惑合集

1.const int a = 10;    

   const int *p1 = &a;

   const int *p2 =const_cast<int *>(p1);

   *p2 = 2;

   *p1, *p2是2了,为什么a 还是10? 但&a, *p1, *p1在输出的地址是相同的啊!

   

   a是const在编译的时候的值已经确定,为常量。用以下代码来说明为什么。

#include <stdio.h>

void f()
{
   const int a = 10;
   const int *p1 = &a;
   int *p2 = const_cast<int *>(p1);
   *p2 = 2;
   int t = *p1 + *p2;
   printf("%d %d", *p1, *p2);
}

反汇编如下

	.file	"why_const_to_nonconst.cpp"
	.section .rdata,"dr"
LC0:
	.ascii "%d %d\0"
	.text
.globl __Z1fv
	.def	__Z1fv;	.scl	2;	.type	32;	.endef
__Z1fv:
LFB8:
	pushl	%ebp
LCFI0:
	movl	%esp, %ebp
LCFI1:
	subl	$40, %esp
LCFI2:
	movl	$1, -24(%ebp)	;   const int a = 1;
	leal	-24(%ebp), %eax	;
	movl	%eax, -12(%ebp)	;   const int *p1 = &a;
	movl	-12(%ebp), %eax	;
	movl	%eax, -16(%ebp)	;   int *p2 = const_cast<int *>(p1);
	movl	-16(%ebp), %eax	;
	movl	$2, (%eax)	;   *p2 = 2;
	movl	-12(%ebp), %eax	;
	movl	(%eax), %edx	;get *p1
	movl	-16(%ebp), %eax	;
	movl	(%eax), %eax	;get *p2
	leal	(%edx,%eax), %eax ;
	movl	%eax, -20(%ebp)	  ;   int t = *p1 + *p2;
	;; 以下是printf的传参数
	movl	-16(%ebp), %eax	  ;
	movl	(%eax), %edx	  ;get *p1
	movl	-12(%ebp), %eax	  ;
	movl	(%eax), %eax	  ;get *p2
	movl	%edx, 8(%esp)	  ;8(%esp) = *p1
	movl	%eax, 4(%esp)	  ;4(%esp) = *p2
	movl	$LC0, (%esp)
	call	_printf
	leave
LCFI3:
	ret
LFE8:
	.def	_printf;	.scl	2;	.type	32;	.endef
显然,p1,p1的值是相同的,即指向同一个位置。执行*p2 = 2, *p1,*p2就是2。

修改原来的代码如下,与上述代码进行对比。

#include <stdio.h>

void f()
{
   const int a = 10;
   const int *p1 = &a;
   int *p2 = const_cast<int *>(p1);
   *p2 = 2;
   int t = *p1 + *p2 + a;//修改的代码
   printf("%d %d", *p1, *p2);
}

	.file	"why_const_to_nonconst.cpp"
	.section .rdata,"dr"
LC0:
	.ascii "%d %d\0"
	.text
.globl __Z1fv
	.def	__Z1fv;	.scl	2;	.type	32;	.endef
__Z1fv:
LFB8:
	pushl	%ebp
LCFI0:
	movl	%esp, %ebp
LCFI1:
	subl	$40, %esp
LCFI2:
	movl	$10, -24(%ebp)
	leal	-24(%ebp), %eax
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	movl	%eax, -16(%ebp)
	movl	-16(%ebp), %eax
	movl	$2, (%eax)
	movl	-12(%ebp), %eax
	movl	(%eax), %edx
	movl	-16(%ebp), %eax
	movl	(%eax), %eax
	leal	(%edx,%eax), %eax ; tmp = *p1 + *p2
	addl	$10, %eax	; result = tmp + a
	movl	%eax, -20(%ebp)	; int t = result
	movl	-16(%ebp), %eax
	movl	(%eax), %edx
	movl	-12(%ebp), %eax
	movl	(%eax), %eax
	movl	%edx, 8(%esp)
	movl	%eax, 4(%esp)
	movl	$LC0, (%esp)
	call	_printf
	leave
LCFI3:
	ret
LFE8:
	.def	_printf;	.scl	2;	.type	32;	.endef

addl	$10, %eax	; result = tmp + a
可以看到a被直接用常量10代替, 由此可以看到编译器在编译时将const常量替换成“常量”。

 &a虽然是a的地址,如果&a这个盒子所存储的东西被修改了, 与a没有关系。因为在编译的时候a被替换成常量了,如上面的10。

由以上可以看到a在编译时已经被替换成真正的常量,&a位置和*p1和*p2是指向相同的地址的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值