const修饰的常量也是可以被修改的!真的是世界上唯一不变的是变化

这里我用的编译器是Dev c++进行测试的,在研究芯片代码加密的时候偶然发现的const常量也是可以被恶意修改的,所以我在Dev c++里进行了测试,结果发现果不其然。但是这种行为出现在C/C++里我个人觉得是不难理解的,使用C语言风格的强制类型转换本来就是强大而又带有危险的,并且我认为c/c++提供关键字const其实只是提供了语义上的保护,而只要是存在于可读写的内存中,通过恶意的行为总是可以修改所谓的const常量。

#include <stdio.h>

int main(void)
{
const int a = 3;
int *p = (int *)(&a);

*p = 1;
printf("%d,%d\n", *p, a);
return 0;
}

首先我用了这段代码,编译通过了,并且运行的结果是1,3

这明显是不符合预期的,看似a的值没有变化,但是*p却变化了,于是我果断加上了关键字volatile来修饰a,如下:

volatile const int a = 3;

这下的运行结果就是1,1了

原文地址:https://www.cnblogs.com/veaxen/p/9185369.html

时间: 2024-11-11 15:09:09

const修饰的常量也是可以被修改的!真的是世界上唯一不变的是变化的相关文章

const修饰的常量 不能被直接修改 但是可以通过指针进行间接修改

大家都知道如下代码中,被const限定的a是不可以被直接修改的 void main() { const int a = 3; a=1; } 在C++中const修饰的常量,不能被直接修改,但是可以通过指针进行间接修改 来看下面的例子:           原意是想通过指针修改const常量a的值,但是运行后发现输出的a依然是3,a的值表面上并没有被改变. 但是查看内存窗口,发现a已经被改变,这里是编译器优化导致的,遇见a时编译器直接从寄存器中读取3给a,而不从内存中读取! 为了改善这种状况,我们

const与readonly常量

const与readonly都是用来定义常量,但是它们有什么区别呢? 下面我们来简要的说明一下: const修饰的常量是编译时常量,如:public const String PI=3.1415;什么是编译时常量,通俗来讲就是指你在声明时,必须要进行赋值(也就是初始化),如果不赋值,编译时会出现说“常量字段要求提供一个值”的异常. readonly修饰的是运行时常量,可以在声明中赋值,也可以在构造函数中赋值(注意只能在这两个地方赋值). http://www.cnblogs.com/royenh

Delphi 中 函数参数中的 const 修饰符的本质以及注意事项

来自:http://blog.csdn.net/farrellcn/article/details/9096787 ------------------------------------------------------------------------------ 很多书籍中说函数参数如果是String类型的,如果在函数内部不改变参数的值,使用 const 修饰符会加快程序的执行速度,至于如何加快的?有的人说是因为 const 函数保证了参数字符串不会被复制.以前也没有对这个问题深入研究

新标准中set的迭代器it有const修饰符,如何去掉

新的C++11标准中,set的迭代器it有const修饰符,那么对它元素的修改就必然不能成功了.但是有时候遇到要修改stl set元素的问题,这个问题一般的解决方法是先erase这个元素,然后再insert.如果利用const_cast(*it)把it映射成一个引用的对象,那么就可以对它进行修改了.const_cast<node*>(&(*it))->b = 10;

C++中 容易忽视的const 修饰符

C++可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的有点: (1)const常量有数据类型,而宏常量没有数据类型.编译器可以对const进行类型安全检查,而后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误!(如类型不匹配问题) (2)编译器处理方式不同.define宏是在预处理阶段展开,const常量是编译运行阶段使用. (3)存储方式不同.define宏仅仅是展开,有很多地方使用,就展开多少次,不会分配内存.const常量会在内存

const修饰符简述

1.const限定符的使用 1)定义const常量:const可以将一个对象变成常量,不可被修改(只读类型),在定义时必须进行初始化.例如: const double mathPI = 3.141592653; 2)修饰函数的参数.返回值等.被const修饰的东西将不再改变: 3)若在整个程序中使用其他文件的变量: //若变量为非const //file_1.cpp int months = 10; //file_2.cpp extern int months; //const修饰的变量 //f

C++的const修饰

C++的const修饰 ?const的两个用途? (1)可以定义 const 常量  (2)const 可以修饰函数的参数.返回值. const的好处 (1)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患! (2)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性! (3)可以节省空间,避免不必要的内存分配(常量宏)! (4)提高了效率. 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为     一个编译期间的常量,没有了存储与读内存的操作

static extern const修饰符

const const修饰的东西不能被修改(由左至右解读-->顺时针螺旋法则) 指针类型根据位置的不同可以理解成3种情况: 1.常量指针 NSString * const pt1; //常量指针,指向一个字符串 //pt1初始化之后不能赋值,指向的对象值可以修改. //定义字符串常量 //NSString* const [email protected]"123"; @"123"存储在文字常量区,相同的字符串只存储一份 NSString* [email pro

const修饰类的成员函数

<Effective C++>里面说,尽量使用const,const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当const修饰类的成员函数时,成员函数有什么特点. 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变. 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函