免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: liaoweijun
打印 上一主题 下一主题

const总结 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-07-14 21:02 |只看该作者
我说一下VC中的实现:
VC中const 变量实际上是放在符号表中的,和define实现一样,但有类型检查
你可以试验一下:
const int a = 100; //a不占内存空间
int *p = (int*)&a; // 在此为a分配空间并初始为100,如果不用到a的地址,是不会为其分配空间的
*p = 200;
cout << a << endl; //输出仍为100,从符号表中取得
cout  << *p << endl; //输出为200
我记得在林锐的《高质量程序设计C++/C》中讲到过

[ 本帖最后由 zszjxh 于 2008-7-14 21:43 编辑 ]

论坛徽章:
0
12 [报告]
发表于 2008-07-14 21:39 |只看该作者
const int a =100;
int *p = &a;
*p = 200;

得到个编译错误,
d:\proj\t\t.cpp(14): error C2440: “初始化” : 无法从“const int *__w64 ”转换为“int *”
环境是.net 2003

论坛徽章:
0
13 [报告]
发表于 2008-07-14 21:43 |只看该作者
原帖由 blackuhlan 于 2008-7-14 21:39 发表
const int a =100;
int *p = &a;
*p = 200;
得到个编译错误,
d:\proj\t\t.cpp(14): error C2440: “初始化” : 无法从“const int *__w64 ”转换为“int *”
环境是.net 2003

sorrry,我疏忽了
应为:int *p = (int *)&a;
我已把上面改正了。

[ 本帖最后由 zszjxh 于 2008-7-14 21:44 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2008-07-14 22:40 |只看该作者

回复 #13 zszjxh 的帖子

注意你使用了强制类型转换,这样做的话就失去const的意义了,而且在有的系统中会出现运行时错误

论坛徽章:
0
15 [报告]
发表于 2008-07-14 23:21 |只看该作者
原帖由 blackuhlan 于 2008-7-14 22:40 发表
注意你使用了强制类型转换,这样做的话就失去const的意义了,而且在有的系统中会出现运行时错误

我只是测试VC中const修饰的变量不占实际空间。
ps:强制类型转换怎么会出现错误呢?

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
16 [报告]
发表于 2008-07-15 09:26 |只看该作者
注意常量优化。

我记得c/c++是遵循“鸭子哲学”的——如果一件事物看起来像鸭子,把它和其它鸭子放到一起也没办法找出差别,那么它就是鸭子^_^


c/c++中的const就是有地址的变量;但如果你不去探察它的地址,编译器会偷偷把它替换成立即数(以节约存储空间和寻址时间)——虽然此时它已经失去了地址这一属性;但既然你没有用到这个属性,你就永远不会知道现在的这个const已经没有存储地址了。

与之相反,对于#define A 100,你是永远取不到A的地址的,所以它不是常量。


总结:const声明的是不折不扣的有地址的常量;除非探测黑盒子内部,否则这个说法永远正确。

PS: 如果一本书不能准确区分“标准定义”和“实践时的优化与折中”,那么它的价值是要大打折扣的。



另回12楼:   可曾试过const_cast?

论坛徽章:
0
17 [报告]
发表于 2008-07-15 09:36 |只看该作者
原帖由 shan_ghost 于 2008-7-15 09:26 发表
注意常量优化。

我记得c/c++是遵循“鸭子哲学”的——如果一件事物看起来像鸭子,把它和其它鸭子放到一起也没办法找出差别,那么它就是鸭子^_^


c/c++中的const就是有地址的变量;但如果你不去探察它的地 ...



受益匪浅!

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
18 [报告]
发表于 2008-07-15 09:38 |只看该作者
加一点提示:

const_cast一般仅用于兼容旧的库函数。

如: char * strcpy(char *, [const] char *)
旧的库函数是不支持const声明的;因此如果想把string a; a.c_str() 返回的东西(一个const char *)当作拷贝源(类型为char *),那么调用strcpy是会被编译器拒绝的。

原因就是a.c_str()返回的字符串是const的,不允许修改。

但另一方面,我们知道strcpy不会修改源字符串;所以就可以安全的使用const_cast<>去掉a.c_str()返回的const char *的const属性。


除了上述这类情况外,其他对const_cast(或c风格cast)的滥用,几乎都会撞上“常量优化”及其他大铁板,落个头破血流的下场。

[ 本帖最后由 shan_ghost 于 2008-7-15 09:49 编辑 ]

论坛徽章:
0
19 [报告]
发表于 2008-07-15 09:48 |只看该作者
原帖由 zszjxh 于 2008-7-14 21:02 发表
我说一下VC中的实现:
VC中const 变量实际上是放在符号表中的,和define实现一样,但有类型检查
你可以试验一下:
const int a = 100; //a不占内存空间
int *p = (int*)&a; // 在此为a分配空间并初始为100, ...


错。
const int a = 100; // 一般情况下,在这句执行前函数就应已经为它分配好栈空间了,不占空间的是100

论坛徽章:
0
20 [报告]
发表于 2008-07-15 09:52 |只看该作者
原帖由 shan_ghost 于 2008-7-15 09:26 发表
注意常量优化。

我记得c/c++是遵循“鸭子哲学”的——如果一件事物看起来像鸭子,把它和其它鸭子放到一起也没办法找出差别,那么它就是鸭子^_^


c/c++中的const就是有地址的变量;但如果你不去探察它的地 ...


有什么鸭子不鸭子的,优化就是优化,等价性证明出错什么鸭子都没用。
所以理解const的标准语义才是最重要的,编译器必须语义等价于它。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP