首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

c跟c++编译器对const修饰的局部变量的不同处理

2013-06-26 
c和c++编译器对const修饰的局部变量的不同处理#include stdio.h#include stdlib.h#include string.h

c和c++编译器对const修饰的局部变量的不同处理


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
const int l_con_val = 2;
printf("addr of l_con_val=%p\n",&l_con_val);
printf("l_con_val=%d\n",l_con_val);
int *p = NULL;
p = (int*)&l_con_val;
*p = 4;
printf("addr of l_con_val=%p\n",&l_con_val);
printf("l_con_val=%d\n",l_con_val);
printf("addr of p=%p\n",p);
printf("*p=%d\n",*p);
printf("*(&l_con_val)=%d\n",*(&l_con_val));
return 0;
}

对于上面的代码,
使用visual studio 2012编译的结果是
addr of l_con_val=0028FA58
l_con_val=2
addr of l_con_val=0028FA58
l_con_val=2
addr of p=0028FA58
*p=4
*(&l_con_val)=2
使用dev c++ 64位编译结果是
addr of l_con_val=000000000022FD74
l_con_val=2
addr of l_con_val=000000000022FD74
l_con_val=2
addr of p=000000000022FD74
*p=4
*(&l_con_val)=2
使用g++编译的结果是
addr of l_con_val=0xbff60868
l_con_val=2
addr of l_con_val=0xbff60868
l_con_val=2
addr of p=0xbff60868
*p=4
*(&l_con_val)=2
使用gcc编译的结果是
addr of l_con_val=0xbfb1b468
l_con_val=2
addr of l_con_val=0xbfb1b468
l_con_val=4
addr of p=0xbfb1b468
*p=4
*(&l_con_val)=4
出现这个的原因是什么呢? 编译器 C C++ const 局部变量
[解决办法]
引用:
Quote: 引用:

正常情况下,用常数等常量表达式定义的常量,会被常数替换。
而常量地址中的值不会。
所以: 
前三种情况,应该是正常的,当然,也是符合标准的。
最后一种情况,是不正常的,也许也是符合标准的。
正常情况下,你不应该用,任何方式,更改常量的值。
你违反了,使用常量的约定,结果。。。。未定义,呵呵。

经过查找相关的书籍,这正是C和C++对于const的不同处理,
在C中如果定义了const常量,是一定会为它分配存储空间的,c编译器对const常量是外部连接,因此通过指针可以改变局部const的值。
但是在c++中,由于对const的默认行为是内部连接(internal linkage),默认是不会为const常亮分配存储空间的,而是把这个相关定义保存在符号表中(除非对局部const常量使用了取地址操作符'&'或者使用了extern进行声明和定义,才会对const常量分配内存空间),并C++编译器还执行常量折叠(constant folding),所以猜测上面c++编译器的结果对于const 标识符的相关结果应该直接使用了符号表中的值。所以会出现上面c和c++的不同情况!

你的好学精神值得学习,就是这个样子的了。
我的关于正常和不正常的说法如下:

就是说人们对于常量的正常理解是,“常量是不变的”,所以可以直接获取常量的数值,这种理解是正常的理解。
编译器就是用那个常量折叠,直接从符号表里取出那个数,放在使用那个常量的地方,以符合这种正常理解。

而直接使用常量被改变后的值,很不符合“常量是不变的”,这种正常人的思维方式,所以个人认为,这种做法,是不正常的,但是好像这也是符合标准的,
因为使用了把常量看作变量,来使用的方法,

这不符合你和编译器的约定,因为你说,这是常量,可是你还来获取它的地址,并通过地址试图改变,这个常量的值。

C,C++标准的制定者,决定,接受你的这种做法,可是不确保必定会得到,其中的任何一种结果。
让编译器自己决定,如何处理,用这种两面派的手法,来编写程序的结果。

呵呵!!!!

热点排行