为什么在本地声明常量变量值会发生变化?

时间:2015-08-26 11:29:36

标签: c const

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变量时,为什么我没有收到错误?

4 个答案:

答案 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变量的位置完全取决于系统,大多数存储在只读位置,因此尝试写入会导致访问冲突