昨天结贴的帖子貌似接的仓促了点,答案可能不太对

MicroSky2813 2010-01-03 09:11:29
http://topic.csdn.net/u/20100102/14/5b39a94b-3802-495a-a3dc-01e5cc47087d.html

原来结贴的答案很有说服力,

今天看 Thinging In C++ (EN P337 CN P177)里说 const如果用到地址的话,是编译器分配的地址,再给这地址值。用这个解释也能解释原问题

望高手来拍砖
...全文
226 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjcapple 2010-01-05
  • 打赏
  • 举报
回复
好东西,顶起
cranium 2010-01-05
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 microsky2813 的回复:]
引用 11 楼 morilasi 的回复:
引用 9 楼 microsky2813 的回复:
用volatile输出的地址的那个1是什么意思?
volatile表示不做缓存优化,所以不会出现常量折叠的情况


地址是1是什么意思,不用volatile输出地址很和谐,一用volatile地址就成1了
[/Quote]

1不是地址,而是个bool型

volatile const int i = 2;
cout<<(long)&i;
macrojj 2010-01-04
  • 打赏
  • 举报
回复
我觉得 编译器发现是const 后 后面的i 全部用0 给替换了。不是volatile的问题 是常量折叠的问题
macrojj 2010-01-04
  • 打赏
  • 举报
回复
你在const i 的前面用volatile修饰 发现地址变成1 但是值还是0 对不对啊
MicroSky2813 2010-01-04
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 morilasi 的回复:]
引用 9 楼 microsky2813 的回复:
用volatile输出的地址的那个1是什么意思?
volatile表示不做缓存优化,所以不会出现常量折叠的情况
[/Quote]

地址是1是什么意思,不用volatile输出地址很和谐,一用volatile地址就成1了
pw_Start 2010-01-04
  • 打赏
  • 举报
回复
测试下面的代码:
const int i = 0;
int* p = (int*)&i;

*p = 2;
int a = i;

其对应的汇编如下:
const int i = 0;
0041139E mov dword ptr [i],0

int* p = (int*)&i;
004113A5 lea eax,[i]
004113A8 mov dword ptr [p],eax

*p = 2;
004113AB mov eax,dword ptr [p]
004113AE mov dword ptr [eax],2

int a = i;
004113B4 mov dword ptr [a],0
执行完*p = 2之后,i的地址空间里面存的变量已经是2了
但在执行a = i时,编译器只是简单地用0把i替换了
这是编译器优化的结果,这就是所谓的常量折叠

5楼说的也不错
morilasi 2010-01-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 microsky2813 的回复:]
用volatile输出的地址的那个1是什么意思?
[/Quote]volatile表示不做缓存优化,所以不会出现常量折叠的情况
黑风不是大侠 2010-01-04
  • 打赏
  • 举报
回复
持续关注ing……
x642458 2010-01-03
  • 打赏
  • 举报
回复
"常量折叠" 就是在编译器进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。
因为编译器在优化的过程中,会把碰见的const全部以内容替换掉(跟宏似的: #define PI 3.1415,用到PI时就用3.1415代替),这个出现在预编译阶段;但是在运行阶段,它的内存里存的东西确实改变了!!!
MicroSky2813 2010-01-03
  • 打赏
  • 举报
回复
用volatile输出的地址的那个1是什么意思?
pengzhixi 2010-01-03
  • 打赏
  • 举报
回复
google常量折叠
camelisi 2010-01-03
  • 打赏
  • 举报
回复
我错了...
改后的值是p的地址...还是没有变的
camelisi 2010-01-03
  • 打赏
  • 举报
回复
学习来了
将 (*ip)++后的那句 cout << ip <<endl;
改成cout << &ip <<endl; 输出的地址值 却是对的。。
kiwigiving 2010-01-03
  • 打赏
  • 举报
回复
const常量对象,编译时会分情况来。
(1) 没有对常量对象取地址的操作,那么编译器仅直接做替换的工作。
例如:const int i = 5;
sum = i;
编译器在编译的时候就直接将i替换成了5。
(2) 如果有对常量对象取地址的操作,那么会为该常量对象分配一块内存单元。
例如:const int i = 6;
int *p = &i;
编译器会为i分配一块内存块,初始化为6.
cranium 2010-01-03
  • 打赏
  • 举报
回复
我支持原帖4楼的回答,很准确。

具有const的变量,编译器便认为他们是常量。在程序范围内不会变化。
当你通过指针绕过了语言的基本保护功能而改变了一个const的值时,编译器意识不到这点。

所以读i依然是定义时的值,它是从寄存器读取的。

用*ip的方式就不同了,它显示要求去地址取值,它得到的自然是更改过后的数了。

volatile关键字可以使每次需要用到i时,都从内存取。
pengzhixi 2010-01-03
  • 打赏
  • 举报
回复
去搜索下常量折叠
Contemplating 2010-01-03
  • 打赏
  • 举报
回复
学习了:)
beefliu 2010-01-03
  • 打赏
  • 举报
回复
关注

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧