关闭

改变const限定的“常量”

标签: constvolatile编译器优化C
242人阅读 评论(0) 收藏 举报
分类:

  在加深学习C语言const关键字时,产生了一个疑问。const关键字限定的常量真的不可以改变吗?
  不是可以通过指针可以改变内存单元的值吗?那是不是可以通过指针改变const限定的常量呢?
  先看一段代码:

#include <stdio.h>

int main(int argc, char const *argv[])
{
	const int intNum = 10;
	int *pToIntNum = (int *)&intNum;

	*pToIntNum = 100;

	printf("&a = %p\n",&intNum);
	printf("a = %d\n",intNum);

	printf("p = %p\n",pToIntNum);
	printf("*p = %d\n",*pToIntNum);

	return 0;
}

通过gcc 5.1 编译发现,结果如下:

看来指针没有什么用,但是它们的地址是相等的呀。嗯,看来这是一个严重的问题。
于是上网查了一下,发现说的是编译器优化的问题。
其意思是指:当编译器看到const int a = 10;时,可能会做出a的值不会改变的假设,直接把后面的a用10来代替,或者直接使用寄存器里以前存过的a的值,而不是在用*p改变了a的值之后小心地取a的值。

解决方法有两种:

(1)关闭编译优化

(2)强制要求编译器每次都要“小心地”取a的值,不要因为a是const就用a以前的值来代替,即将 const int a = 10改成volatile const int a = 10;

在这里我采用第二种,用volatile关键词限定。

代码如下:

#include <stdio.h>

int main(int argc, char const *argv[])
{
	volatile const int intNum = 10;
	int *pToIntNum = (int *)&intNum;

	*pToIntNum = 100;

	printf("&a = %p\n",&intNum);
	printf("a = %d\n",intNum);

	printf("p = %p\n",pToIntNum);
	printf("*p = %d\n",*pToIntNum);

	return 0;
}
通过原来的编译器编译,结果如下:

附注:这种方法可以通过对部分升级游戏进行逆向工程后随意更改你的等级,当然前提是你会逆向工程。




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6330次
    • 积分:253
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类