以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  你今天volatile了吗?--兑现允诺  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=37450)


--  作者:dspfirmware
--  发布时间:8/31/2006 9:10:00 AM

--  你今天volatile了吗?--兑现允诺
上一篇文章《你今天volatile了吗?--准确定位》(后面简称《准确定位》)主要探讨关于volatile在定义设备寄存器时应该放到什么位置最合适的问题。另外,在文章中也提到下面两个观点:
*对任意数据类型T,C提供一种标准内置的转换。这个转化可以完成从T指针到volatile T指针的转换,并规定其逆过程即volatile T指针向T指针转换为非法。
*const指针和volatile指针在转换规则方面具有相似性。
本篇文章就后一个观点继续深入探讨。
本人认为const指针的转换规则与const指针的基本一致,因此只要我们懂得其中的一种规则,那么另外的一种就可以不攻自破。关键就是要懂得其中的共同规律,而不是去死记硬背一些具体应用。

1.自相矛盾
T *p;
...
void f(T const *qc);
如果调用f(p)将p传入函数,T指针将会转换成const T指针。整个转换过程是自动完成的,不必人为地强制转换T指针。这是一条潜规则。相反,在下面情况下,如果调用g(pc),就会产生编译错误:
T const *pc;
...
void g(T *q);
因为编译器拒绝将const T指针转换成T指针。这也是一条潜规则。
让记住下面的推断:如果你许诺你使用const是不让其它程序改变const对象的内容,那么你自己在后面编写const相关代码时必须要遵守这个许诺。就象一些做官的,表面是一套,背后又是另一套,最后对自己的所做所为不能自圆其说!
下面举个简单的例子来说明诺言是怎么许下,又是怎么被打破的。
假设有人写了下面的代码:
int const *p;
显然,他希望通过const阻止任何有意图去修改const对象的内容的行为,可他又继续写下了"挨扁"的代码:
*p += 3; /*改变p指向的内容*/
++(*p);
因为,他自己又去修改p指针指向的内容,自相矛盾啊!!!
那让我们回头看原先的代码:
T const *pc;
...
void g(T *q);
当你定义const类型的指针pc,等价于你对编译器许诺说我决不允许有代码直接地或间接地甚至潜在地去修改pc指向的内容。当然,我们的编译器是“大好人”,肯定会爽快地答应。接着,你又对编译器许诺说g函数可以修改通过q传入的任何指针的内容。最后你试着调用g(pc)将p通过pc传入g。这时编译器肯定看不过去了,一定会这样地质问你:
你为何将const指针pc传入可能会改变pc指向内容的g函数呢,你不是决不允许其它代码直接地或间接地甚至潜在地去修改pc指向的内容吗,你现在将pc传入g函数不是自己打自己嘴巴吗?嘿嘿,哑口无言了吧!所以,既然做出了许诺,就要坚持到底
继续下面的代码:
T *p;
...
void f(T const *qc);
显然,你许诺编译器说任何代码都可以改变p指向的内容并且你编写的f函数不会改变通过qc传入的其它指针指向的内容。编译器又一次爽快地答应了你。最后你调用了f(p)。这次,编译器只是对你笑笑,心理暗自道:小样你可别让我逮到在f函数中调用诸如g之类可能会改变p指向的代码哦!

2.Const vs Volatile
请转到
http://blog.sina.com.cn/u/4a317b790100051n
继续阅读


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
6,169.922ms