分享
 
 
 

谈谈volatile和const

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

用户:404082727(走尽天涯路)

==================================================

消息组:群/校友录()

==================================================

消息类型:聊天记录

==================================================

2004-12-28 14:50:43 lalala()

const 只是指明后面的变量初始化后不能被赋值。这只是编译时刻的限制。也就是说,

a基本上是一个普通的变量,只是compiler在检查你的代码有没有对它赋值。

在运行时刻,a与别的变量没有区别。

如果int a = i; 合法,const int a = i; 当然合法。因为这样的初始化是在运行时刻

完成的。

const 的值甚至是可以改变的!!!

#include <stdio.h>

int main(int argc, char* argv[])

{

volatile const int a = 0;

int* p = (int*) &a;

*p = 1;

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

}

运行结果:(cygwin, gcc)

*p = 1, a = 1, p = 0x22feec, &a = 0x22feec, &p = 0x22fee8

注意:a与p的位置是紧邻的,都在栈里。如果没有volatile,运行结果是:

*p = 1, a = 0, p = 0x22feec, &a = 0x22feec, &p = 0x22fee8

这完全是编译器自己优化的结果

2004-12-28 14:53:17 漫.ASH()

厚厚,const只是在编译期间申明一下而已,不是用来从硬件上使他成为只读的。

所以有很多方法可以骗过编译器。

2004-12-28 14:53:45 曾经未来()

http://blog.csdn.net/kendiv/archive/2004/12/28/231710.aspx

GCC 中文手册

2004-12-28 14:54:20 lalala()

关键是那个volatile,以前没用过

2004-12-28 14:56:07 iCoding()

是不是volatile和const作用相反,等于没加const?[?]

2004-12-28 14:56:45 lalala()

volatile说这个变量可能会被修改,编译器不会用常量去代替它

2004-12-28 14:57:30 iCoding()

volatile说这个变量可能会被修改

---------------

说和没说一样,变量的值当然会被修改了

2004-12-28 14:58:03 iCoding()

http://www.coresoft.com.ru/ibbs/topic.asp?bbsid=2&topicid=25

2004-12-28 14:58:06 走尽天涯路()

他俩没啥关系吧,volatile告诉编译器不要优化变量

2004-12-28 14:58:46 lalala()

常量

2004-12-28 14:59:14 走尽天涯路()

不是常量的意思,

2004-12-28 14:59:25 曾经未来()

unknown & undefine

应该是是什么值呢?

2004-12-28 14:59:45 lalala()

别说我写的,让人笑话,这是我转的

2004-12-28 15:00:00 iCoding()

lalala

const int a = 0;

int* p = (int*) &a;

*p = 1;这样行不行捏?

2004-12-28 15:00:14 lalala()

可以

2004-12-28 15:00:18 走尽天涯路()

unknown & undefine

应该是是什么值呢?

说的什么呀

2004-12-28 15:00:28 曾经未来()

多元逻辑

2004-12-28 15:00:46 漫.ASH()

不仅不知道,而且未定义

2004-12-28 15:01:26 走尽天涯路()

多元逻辑 指的哪些东西啊

2004-12-28 15:01:46 iCoding()

那就volatile没多大关系,只不过在骗编译器而已,编译器不知道p指向的是啥[;P]

2004-12-28 15:03:08 lalala()

int main(int argc, char *argv[])

{

const int a = 0;

int* p = (int*) &a;

*p = 1;

cout<<a<<endl;

cout<<*p<<endl;

system("PAUSE");

return 0;

}

2004-12-28 15:03:15 lalala()

输出0,1

2004-12-28 15:03:36 漫.ASH()

糟糕的编程风格

2004-12-28 15:04:04 lalala()

int main(int argc, char *argv[])

{

volatile const int a = 0;

int* p = (int*) &a;

*p = 1;

cout<<a<<endl;

cout<<*p<<endl;

system("PAUSE");

return 0;

}

2004-12-28 15:04:10 lalala()

就是1,1了

2004-12-28 15:04:22 lalala()

有了volatile

2004-12-28 15:04:28 漫.ASH()

只要用了强制转换,任何const灰都没用啊

2004-12-28 15:04:45 lalala()

就是1,1了

2004-12-28 15:04:46 iCoding()

[;@]怎么会这样啊?

2004-12-28 15:04:52 lalala(3)

const只能防你不小心

2004-12-28 15:04:59 iCoding(5)

NND...我来试试

2004-12-28 15:05:33 lalala()

你专门去改,当然能改得了

2004-12-28 15:07:10 Ricky(1)

我记得前段时间在群里面和一个网友讨论过

2004-12-28 15:07:48 lalala()

我也看了,说得是第一种情况输出0,1的

2004-12-28 15:07:57 iCoding()

没听到...

2004-12-28 15:08:42 lalala()

就是没加volatile的那种情况,编译器把常量用立即数替换了

2004-12-28 15:09:07 Ricky()

这里可以说是volatile的一种滥用

2004-12-28 15:09:11 走尽天涯路()

volatile类型的限定词,它告诉编译器,变量可以被应用程序本身以外的某个东西进行修改,这些东西包括操作系统,硬件或同时执行的线程等。尤其是,volatile限定词会告诉编译器,不要对该变量进行任何优化,并且总是重新加载来自该变量的内存单元的值。

2004-12-28 15:09:54 unfeng()

volatile只是对编译器的一种暗示,

2004-12-28 15:10:00 iCoding()

const int i=1;

int *p=(int *)&i;

cout<<i<<endl;

cout<<*p<<endl;

2004-12-28 15:10:16 iCoding()

程序输出:

1

1

2004-12-28 15:10:23 iCoding()

2004-12-28 15:10:34 漫.ASH()

有什么晕的?

2004-12-28 15:10:42 lalala()

你没改,

2004-12-28 15:10:53 iCoding()

没修改指针指向值

2004-12-28 15:10:56 Ricky()

当一个变量被定义成const,是否已经在暗示编译器:我不想改变这个变量,既然是如此,我还用volatile去修饰……所以我觉得是滥用了

2004-12-28 15:11:04 lalala()

const int a = 0;

int* p = (int*) &a;

*p = 1;

2004-12-28 15:11:28 漫.ASH()

这样做说明了什么?

2004-12-28 15:11:31 lalala()

你是说发明volatile是脱裤子放屁?

2004-12-28 15:11:55 iCoding()

1

2

2004-12-28 15:12:08 iCoding()

const int i=1;

int *p=(int *)&i;

*p=2;

cout<<i<<endl;

cout<<*p<<endl;

2004-12-28 15:12:34 Ricky(1)

当然不是,在多线程编程中,为了避免错误的优化,是需要的

2004-12-28 15:13:13 lalala()

就是这个:volatile限定词会告诉编译器,不要对该变量进行任何优化,并且总是重新加载来自该变量的内存单元的值。

2004-12-28 15:13:23 lalala()

我们用了他这个特性

2004-12-28 15:13:26 漫.ASH()

明显滥用了啊,本来就是const常量的东西,你还对编译器说不要优化,有什么意思捏?

不过用在类里头到值得商榷啊???

是不是可以让某个mutable的变量不被优化捏?

2004-12-28 15:13:42 Ricky()

nod,这就是我说的滥用

2004-12-28 15:14:28 漫.ASH()

不过用在类里头到值得商榷啊???

是不是可以让某个mutable的变量不被优化捏?

是不是呢?

2004-12-28 15:15:08 Ricky()

ASH请说明一下

2004-12-28 15:15:11 lalala()

不知道正常使用volatile的情况,没碰到过,哪位举个例子

2004-12-28 15:16:06 漫.ASH()

比如一个常量对象里的可变属性,对他用volatile,有意义吗?

2004-12-28 15:18:31 lalala()

(漫.ASH) 15:16:06

比如一个常量对象里的可变属性,对他用volatile,有意义吗?

是反问吗?

2004-12-28 15:18:44 漫.ASH()

疑问

2004-12-28 15:19:20 曾经未来()

我还真没研究过,一般我看到这种东西都跳过的

2004-12-28 15:19:25 lalala(3)

既然是常量对象了怎么还会有可变属性

2004-12-28 15:19:55 曾经未来()

C++不是Java,想要灵活,就不可能不在安全上付出代价

2004-12-28 15:19:58 Ricky()

mutable不就是可变属性吗?

2004-12-28 15:20:00 Ricky()

刚刚在CSDN上看到一段文字,正在消化中

2004-12-28 15:20:01 漫.ASH()

当然有了

2004-12-28 15:20:12 lalala()

贴出来看看

2004-12-28 15:20:09 iCoding()

我就搬起石头砸自己脚了mad

2004-12-28 15:24:56 Ricky()

4.谈谈volatile和”完全const对象”

一个有volatile修饰的类只允许访问其接口的一个子集,这个子集由类的

实现者来控制.用户只有用const_cast才可以访问这个类型的全部接口.而且,

象const一样,类的volatile属性会传递给它的成员.想象const修饰的对

象,它的成员变量是不可修改的,而它通过指针维护的对象或原生变量是可

修改.那么我们想:如果对象维护一个char* ,则它相当于char*

const chrptr ;而不是const char* cosnt chrptr;对于类中的指针你需要

这样修饰以防止它或它维护的资源:cosnt x* xptr;而不是x*const xptr;

因为cosnt 修饰的对象它默认 的行为是延续变量:x* cosnt xptr;

更重要的,volatile修饰的数据,编译器不可对其进行执行期寄存于寄存器的优化.

这种特性,是为了多线程同步的需要.有兴趣者看参看Andrei的GP系列文章.

http://www.chinaunix.net/jh/23/94481.html

2004-12-28 15:26:12 Ricky()

关于volatile关键字的说明以及测试:

http://blog.vckbase.com/iwaswzq/archive/2004/12/05/1896.aspx

2004-12-28 15:26:38 Ricky()

上次也是和lalala讨论过const问题的吧?

2004-12-28 15:26:58 lalala()

我是跟你学习,呵呵

2004-12-28 15:27:11 lalala(3)

我是跟你学习,呵呵

2004-12-28 15:27:14 Ricky()

一起学习

2004-12-28 15:27:49 iCoding()

虚怀若谷啊....偶PF哦

2004-12-28 15:28:32 Ricky()

少笑话我就ok了

2004-12-28 15:29:31 iCoding()

哪有?谁敢笑话跳出来~~~~~

没有吗?没有吗?

哦,真滴没有.....

2004-12-28 15:29:45 iCoding()

ohh

2004-12-28 15:31:13 iCoding()

不过我觉得还是C语言的转换方法更容易懂一点,C++的const_cast<>我就搞不明白...

2004-12-28 15:32:11 Ricky()

C的转换方式可以少输入几个字母,这是我很欣赏的一点,否则我还是使用const_cast<>

2004-12-28 15:32:39 lalala()

26367948(漫.ASH) 15:16:06

比如一个常量对象里的可变属性,对他用volatile,有意义吗?

链接给我看看好吗

2004-12-28 15:32:56 iCoding()

ASH走人啦~~~

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

关于volatile关键字的说明以及测试

作者:九月鹰飞

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

使用该关键字的例子如下:

int volatile nVint;

当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。

例如:

volatile int i=10;

int a = i;

...

//其他代码,并未明确告诉编译器,对i进行过操作

int b = i;

volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。

注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无volatile关键字,对程序最终代码的影响:

首先,用classwizard建一个win32 console工程,插入一个voltest.cpp文件,输入下面的代码:

#include <stdio.h>

void main()

{

int i=10;

int a = i;

printf("i= %d\n",a);

//下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道

__asm {

mov dword ptr [ebp-4], 20h

}

int b = i;

printf("i= %d\n",b);

}

然后,在调试版本模式运行程序,输出结果如下:

i = 10

i = 32

然后,在release版本模式运行程序,输出结果如下:

i = 10

i = 10

输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。下面,我们把 i的声明加上volatile关键字,看看有什么变化:

#include <stdio.h>

void main()

{

volatile int i=10;

int a = i;

printf("i= %d\n",a);

__asm {

mov dword ptr [ebp-4], 20h

}

int b = i;

printf("i= %d\n",b);

}

分别在调试版本和release版本运行程序,输出都是:

i = 10

i = 32

这说明这个关键字发挥了它的作用!

iwaswzq 于2004/12/4/16:15:http://www.vckbase.com/document/viewdoc/?id=1312

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有