volatile关键字
volatile用来修饰变量,volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
volatile 声明时语法:int volatile 变量;
volatile 的作用:当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据,而且读取的数据立刻被保存。
#include <stdio.h>
void main()
{
int i = 10;
int a = i;
printf("i = %d", a);
// 下面汇编语句的作用就是改变内存中 i 的值
// 但是又不让编译器知道
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf("i = %d", b);
}
结果在Debug下运行a=10,b=32;
在Release下运行,a=10,b=10;
因为在Release模式下,会发布版本,不对源代码进行调试,编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
而在Debug模式下,调试版本,包含调试信息,所以容量比 Release 大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂),便于程序员调试。Debug 模式下生成两个文件,除了 .exe 或 .dll 文件外,还有一个 .pdb 文件,该文件记录了代码中断点等调试信息 。
因此运行顺序为,初始化i=10,然后将i=10的值赋给a,即a=10,然后改变i地址的值,当执行"b=i"语句的时候,会进行优化处理,即直接将a地址里的值直接赋给b的地址,即得到a=10;b=10;这样错误的结果。
使用volatile ,在i前面用volatile修饰得:
#include <stdio.h>
void main()
{
volatile int i = 10;
int a = i;
printf("i = %d", a);
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf("i = %d", b);
}
结果,a=10;b=32;
通过volatile修饰变量i,程序识别到volatile变量i,每次对变量i进行访问都会从i的地址进行访问遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
&spm=1001.2101.3001.5002&articleId=140752612&d=1&t=3&u=c95e1d57165e4d3e8ae0612b222b8d06)
386

被折叠的 条评论
为什么被折叠?



