C++的UB行为

真的很不想讲这个,但是有些人就是死脑筋一样,我今天就讲一个UB的情况

#include<iostream>
int main()
{
	const int num = 1;
	int* p_num = (int*)&num;
	*p_num = 2;
	int a = num, b = *p_num;
	std::cout << num << std::endl;
	std::cout << a << std::endl;
	std::cout << b << std::endl;

}

这是一段非常简单的代码,运行结果如下:

这是一种UB,那么为什么是这种结果。看下面

 听好了,再听不懂真别学了。这是在MSVC编译器的环境下,首先明确一个概念,C++内const修饰表示常量,在编译器看来这块内存就像被标记了一样,永远,是永远无法被改变,这是常量,不要抠字眼,在ISO委员会的标准中是如此。那么修改分为直接修改和间接修改。

1、直接修改,没什么好说的直接error退出程序,非法行为

2、间接修改,编译器会对这种行为做优化,编译器会无视你对常量间接修改的操作,也不会中断报错,这个时候看图,指针指向了常量的num,解引用就是1,这个注意看上面内存&p_num,此时的指针地址,第二图指针的地址,发现了吗,指针的地址变了,或许不该这么说,这是指针自身的地址,它变了表示着,此指针非彼指针,编译器的优化是,既然你想要给常量赋值2,修改它,我肯定是不允许的,但是我可以让你满足你的指针指向的是2,编译器直接替换了一个新的指针,这也是为什么指针自身的地址变了,表示着这是编译器开辟了一块内存,内存的值是2,把这块内存的地址作为了p_num,所以最好常量还是1,b被赋值为*p_num也就是地址*取值为2,,b变成了2.

 最后说一句,这个东西动点脑子就看的出来,了解这些编译器的具体行为其实未必重要。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值