免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1962 | 回复: 7
打印 上一主题 下一主题

你今天volatile了吗?--兑现允诺 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-31 10:00 |只看该作者 |倒序浏览
上一篇文章《你今天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
继续阅读

论坛徽章:
0
2 [报告]
发表于 2006-08-31 10:07 |只看该作者
我觉得lz好像弄错了下面两个概念:
int const *p
const int *p
第一个是指针p是只读的,当然可以修改p指向的地址中的内容。
第二个是指针p指向的地址的内容是只读的。

论坛徽章:
0
3 [报告]
发表于 2006-08-31 10:41 |只看该作者
虽然大家都知道这些常识,但这几个比喻还真有意思。。

论坛徽章:
0
4 [报告]
发表于 2006-08-31 10:46 |只看该作者
原帖由 sway2004009 于 2006-8-31 10:07 发表
我觉得lz好像弄错了下面两个概念:
int const *p
const int *p
第一个是指针p是只读的,当然可以修改p指向的地址中的内容。
第二个是指针p指向的地址的内容是只读的。



应该是你记错了,两个都是让p指向的内容只读。对于const的用法最不容易搞错的的就是这样
让const修饰紧挨着的前面的内容,比如
int const *p,它前面是int,所以让p指向的内容保持不变
int *const p =&j ,它前面是个*,因此p本身不能变。

象这样const int* p,不怎么好说,不过也是让 p指向的内容不变。

论坛徽章:
0
5 [报告]
发表于 2006-08-31 13:56 |只看该作者
const int *p  一个指向整形的指针常量
int const *a 一个指向常量类型的指针
int *const a 一个常量指针指向整形

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2006-09-01 09:16 |只看该作者
原帖由 sway2004009 于 2006-8-31 10:07 发表
我觉得lz好像弄错了下面两个概念:
int const *p
const int *p
第一个是指针p是只读的,当然可以修改p指向的地址中的内容。
第二个是指针p指向的地址的内容是只读的。

呵呵,上面两个的语义一模一样
不可通过该指针去修改内容

论坛徽章:
0
7 [报告]
发表于 2006-09-01 10:25 |只看该作者

回复 5楼 新手上路2世 的帖子

const int *p , 和 int const *p 是一样的,5楼说错了。

论坛徽章:
0
8 [报告]
发表于 2006-09-01 10:47 |只看该作者
volatile是一个很有争议的东西,至少在关于volatile的simple type的运算的原子性还没有哪个人敢拍着胸脯说没问题。
另外:
"T const *pc;
...
void g(T *q);
当你定义const类型的指针pc,等价于你对编译器许诺说我决不允许有代码直接地或间接地甚至潜在地去修改pc指向的内容。"
这句恐怕你弄错了吧.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP