C++ const深入理解

如下代码,为什么main会返回0,而不是1呢?

int main() {
    
    
    const int a = 0xA5A5;
    int *b = (int *)(&a);
    *b = 333;
    if (*b == a) {
    
    
        return 1;
    }
    return 0;
}

如果a是const变量,不能变。但是我们通过a的地址改变了它的值呀。

我翻了《C++编程思想》还有好多论坛和博客,讲的都太罗嗦了。

  1. const关键字的初衷是什么?
  • 替换宏定义
  • 便于调试
  • 安全检查
  1. 怎么实现?
    我们知道程序生成的整个过程,预编译->编译->汇编->链接。
    宏定义替换在预编译时期替换宏。其实,const常量也是相同的,只不过这个过程放在了编译阶段。
    const常量是在编译阶段做替换的,编译程序会根据常量表把const变量替换成立即数
    如下代码,生成的汇编代码和第一部分的生成的汇编代码是一模一样的。
int main() {
    
    
    const int a = 0xA5A5;
    int *b = (int *)(&a);
    *b = 333;
    if (*b == 333) {
    
    
        return 1;
    }
    return 0;
}

除了做替换之外,a还和其他变量一样分配了内存空间。
而这部分内存空间再怎么变,a早就在编译阶段替换成立即数了,所以是改变不了的。

有人问,那么这个const变量是存在什么地方呢?常量表在哪里?
常量表,是对编译程序而言的,它是编译程序的内存,而我们最后在结果程序中是看不到的,是没有这个概念的。const变量被分成了,汇编代码中的立即数(不能改变)和分配的对应一块内存。后者方便我们调试。
如果你用gdb调试第一块代码,就会发现在gdb中,运行到第5行时,a的值是333,但却没走第8行。理解上面的论述,也就知道为什么gdb在这会不靠谱了。

const object - an object whose type is const-qualified, or a non-mutable subobject of a const object. Such object cannot be modified: attempt to do so directly is a compile-time error, and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.

来自cppreference 意思就是,通过引用或者指针来改const的值是不靠谱的,别这样做。

附汇编代码

	.file	"aa.cpp"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$42405, -12(%rbp)
	leaq	-12(%rbp), %rax
	movq	%rax, -8(%rbp)
	movq	-8(%rbp), %rax
	movl	$333, (%rax)
	movq	-8(%rbp), %rax
	movl	(%rax), %eax
	cmpl	$333, %eax  ##注意这里,是直接用333来比较
	jne	.L2
	movl	$1, %eax
	jmp	.L4
.L2:
	movl	$0, %eax
.L4:
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-4)"
	.section	.note.GNU-stack,"",@progbits

猜你喜欢

转载自blog.csdn.net/niu91/article/details/109759891
今日推荐