Scenerio 1 :在const
内声明main()
变量时,即本地
#include <stdio.h>
#include <conio.h>
main()
{
const int a = 45;
* ((int*)&a)=50;
printf("%d\n",a);
getch();
}
输出MVC ++:
α= 50
Scenerio 2 :const
变量在main()
之外声明,即全局
#include <stdio.h>
#include <conio.h>
const int a = 45;
main()
{
* ((int*)&a)=50;
printf("%d\n",a);
getch();
}
输出MVC ++:
未处理的异常......违规行为。
我理解为什么在尝试修改全局定义的const
变量时出现错误。但是,当我尝试修改本地定义的const
变量时,为什么我没有收到错误?
答案 0 :(得分:9)
您的代码生成exception-safety guarantees。
如果您尝试修改任何cast
变量通过非const限定类型变量(例如:const
离开C11
- ness),它是UB。
引用const
标准,章节§6.7.3,(类型限定符)
如果尝试通过use修改使用const限定类型定义的对象 如果是非const限定类型的左值,则行为未定义。 [...]
FWIW,这不依赖于在全局范围或本地范围内定义的变量,在两种情况下都是UB。
正如undefined behaviour在他的Mr. Lundin中对这个的情况很好地描述的那样,它可能发生在本地范围- (void)viewDidLayoutSubviews {
}
变量取代堆栈中因此可以以某种方式变得可修改。因此,您没有看到Access违规错误(崩溃)。但是,请记住,标准保证接近。
答案 1 :(得分:9)
尝试修改const
变量的内容是未定义的行为,这意味着它是一个错误,任何事情都可能发生。
所以不能保证第一个案例也会崩溃。为什么你碰巧侥幸逃脱它,可能是因为本地范围内的const
变量往往会在运行时存储在堆栈中。这意味着它恰好是您可以写入的内存区域。但是当你在文件范围内发布它时,它最终会进入只读内存段,从而导致崩溃。
答案 2 :(得分:6)
修改const
对象是未定义的行为。
N3337 [dcl.type.cv]/4:
除了可以修改声明mutable
的任何类成员之外,任何在其生命周期内修改const
对象的尝试都会导致未定义的行为。 < / p>
两者的行为以及您可以想象的任何其他事物都是有效的。
答案 3 :(得分:3)
一旦将变量声明为const
,就不应该使用指向该位置的指针来更改存储的值。这会调用未定义的行为。
存储const
变量的位置完全取决于系统,大多数存储在只读位置,因此尝试写入会导致访问冲突