返回信息流☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 13:31:19 2011) 提到:
RT
针对“const变量不可改变,即便是通过地址也不可变”做了如下测试:
const int n = 9;
printf("%d ",n);
int *p = (int*)(&n);
const int *a = &n;
*p = 5;
int m = n;
int t = *p;
printf("%d ",*(p));
printf("%d ",*(a));
printf("%d ",*(&n));
printf("%d ",n);
printf("%d ",m);
打印的结果是:
9 5 5 9 9 9
跟踪显示,n的存储地址通过*p = 5已经变成5,n的地址也没变,但是m=n 之后,m还是等于9。。。
9是哪来的啊?
各种不解。。。求大牛。。
更奇怪的结果。。。。。。。。
更多不解。。
{
int x = 9;
const int n = x;
printf("%d ",n);
int *p = (int*)(&n);
const int *a = &n;
*p = 5;
int m = n;
int t = *p;
printf("%d ",*(p));
printf("%d ",*(a));
printf("%d ",*(&n));
printf("%d ",n);
printf("%d ",m);
}
printf("\n");
{
const int n = 9;
printf("%d ",n);
int *p = (int*)(&n);
const int *a = &n;
*p = 5;
int m = n;
int t = *p;
printf("%d ",*(p));
printf("%d ",*(a));
printf("%d ",*(&n));
printf("%d ",n);
printf("%d ",m);
}
打印的结果是:
9 5 5 5 5 5
9 5 5 9 9 9
☆─────────────────────────────────────☆
iam19891211 (【洛阳亲友如相问】 【就说我在学六楼】) 于 (Mon Apr 11 14:34:49 2011) 提到:
const在编译时会被编译为静态成员,它确定于编译时期,属类型级,通过类型来访问。
百度的
☆─────────────────────────────────────☆
a206206 (右将军府副手) 于 (Mon Apr 11 14:52:42 2011) 提到:
c的const和c++的不一样
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 15:50:49 2011) 提到:
谢谢啦。不过还是不太明白。。。[em17][em17]
【 在 iam19891211 的大作中提到: 】
: const在编译时会被编译为静态成员,它确定于编译时期,属类型级,通过类型来访问。
: 百度的
☆─────────────────────────────────────☆
liaowang11 (Bill) 于 (Mon Apr 11 15:57:56 2011) 提到:
貌似在.rodata里面, 映射到内存中为只读?
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Mon Apr 11 16:08:34 2011) 提到:
这个应该不是吧。。。
如果是运行时才能确定值的(例const int m=n,n不是编译时可知的一个值),怎么都不可能放到.rodata的。。。
【 在 liaowang11 的大作中提到: 】
: 貌似在.rodata里面, 映射到内存中为只读?
: --
☆─────────────────────────────────────☆
times123 (每天写一个helloworld喵) 于 (Mon Apr 11 16:27:28 2011) 提到:
同样的代码,在我的系统中是9 5 5 5 5 5
C中的const,无责任推测,是编译器的概念,编译时,如果有任何对const符号的赋值行为,都无法通过编译。
C中的const变量,在内存中并没有任何特殊的地方,如果得到const的地址,可以更改地址中的值,如代码所示。
gcc编译,-Wall,但还是并没有任何warning。
至于楼主的测试结果,猜测是编译器的优化所致,嗯。
☆─────────────────────────────────────☆
times123 (每天写一个helloworld喵) 于 (Mon Apr 11 16:38:21 2011) 提到:
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
开启-O2结果为:9 5 5 9 9 9
不开启-O2结果为:9 5 5 5 5 5
我了个去,也不用去看汇编代码了。。。就是编译器优化代码的缘故。编译器故做聪明,在int m=n时,并没有从内存中读取n的值,直接把n当做常量处理了,就是这样。
-------------------
zx@zx-laptop:~$ gcc -o t -Wall -O2 t.c
zx@zx-laptop:~$ ./t
9 5 5 9 9 9 5 zx@zx-laptop:~$
zx@zx-laptop:~$ gcc -o t -Wall t.c
zx@zx-laptop:~$ ./t
9 5 5 5 5 5 5
//多添了一行打印t值的代码。。。int t = *p; 就是打印这个t值的代码。打印这个t值,基本上就是答案了。
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 16:44:28 2011) 提到:
但是,百度面试的时候,面试官告诉我,const不管通过什么方式都能改变,即便是通过地址也不行。。。所以才引发了我对这个东西的探索。
如果真是编译器优化的结果,那这是什么一个优化原则呢?
【 在 times123 的大作中提到: 】
: 同样的代码,在我的系统中是9 5 5 5 5 5
: C中的const,无责任推测,是编译器的概念,编译时,如果有任何对const符号的赋值行为,都无法通过编译。
: C中的const变量,在内存中并没有任何特殊的地方,如果得到const的地址,可以更改地址中的值,如代码所示。
: ...................
☆─────────────────────────────────────☆
times123 (每天写一个helloworld喵) 于 (Mon Apr 11 17:01:54 2011) 提到:
=。=并不是说百度的面试官说的都是对的,他也是人,也能犯错,不是吗?
const不能改变的是C++,但C和C++还是有一些区别的。
代码说明了这个问题,嗯。
可以加-g选项读汇编代码。
printf("%d ",*(p));//自然打印5了。
printf("%d ",*(a));//自然打印5了。
printf("%d ",*(&n)); //如果优化的话,*(&n)=。=,首先优化成n,n又是个const常量,然后没从内存中读取n。。。这个值比较特殊,是编译时就已经确定了的值。
printf("%d ",n);//打印n,没从内存中读取n,而是编译器已经知道n为9
printf("%d ",m);//m等于n,同样没从内存中读取n呗,这次读取被编译器优化掉了。
printf("%d ",t); //这个就得从内存中读取值了。打印的值,就是5,嗯
开启高优化级别后,优化掉一次内存读取,就是这样。n值是编译时可知的,那么这个n的符号,可直接用字面值常量'9'代替.编译器维护一个表格,当需要n时直接查表,不就优化掉一次内存访问了吗?
【 在 dyrdyr 的大作中提到: 】
: 但是,百度面试的时候,面试官告诉我,const不管通过什么方式都能改变,即便是通过地址也不行。。。所以才引发了我对这个东西的探索。
: 如果真是编译器优化的结果,那这是什么一个优化原则呢?
: 【 在 times123 的大作中提到: 】
: ...................
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 17:06:07 2011) 提到:
那加了优化之后,系统把“9”放到哪里去了呢。。另外找了一个地方存放n原来的值?
你这么说来,const变量是可以通过地址改变。。那就是百度的那个面试官错了。。
【 在 times123 的大作中提到: 】
: gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
: 开启-O2结果为:9 5 5 9 9 9
: 不开启-O2结果为:9 5 5 5 5 5
: ...................
☆─────────────────────────────────────☆
times123 (每天写一个helloworld喵) 于 (Mon Apr 11 17:13:19 2011) 提到:
楼主的代码是有一些特殊的。const n值是编译时可知的。
所以,在开启编译器优化选项后,很可能就优化掉了对n这个对象的内存读取。举个不太合适的例子,就像编译器对待define常量类似。
但对代码稍微更改之后:
int x;
scanf("%d",&x);
const int n = x;此时n值不再是编译时可知了,此时编译器便没有办法优化掉对n值的内存访问了。
--------------------
代码结果为:
zx@zx-laptop:~$ gcc -o t -Wall t.c
zx@zx-laptop:~$ ./t
7
7 5 5 5 5 5 5
zx@zx-laptop:~$ gcc -o t -Wall -O2 t.c
t.c: In function ‘main’:
t.c:6: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
zx@zx-laptop:~$ ./t
7
7 5 5 5 5 5 5
开启更高的优化级别:
zx@zx-laptop:~$ gcc -o t -Wall -O3 t.c
t.c: In function ‘main’:
t.c:6: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
zx@zx-laptop:~$ ./t
7
7 5 5 5 5 5 5
--------------------------------
结论,帖子中出现的怪异现象,是因为编译器的优化所致。编译器对编译时已知的常量进行了优化。如果n值编译时不可知,就不会存在类似的现象了。
另,楼主本来的问题是c中的const对象。C中的const,无责任推测,是编译器的概念,编译时,如果有任何对const符号的赋值行为,都无法通过编译。C中的const变量,在内存中并没有任何特殊的地方,如果得到const的地址,可以更改地址中的值,如代码所示。
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 17:14:17 2011) 提到:
受教了。。谢谢。。
我说可以,百度的面试官,反问了我一句,“那他为什么还要叫常量呢?”。。呵呵,原来如此。。
c++中,const不能改变,你测试了?
【 在 times123 的大作中提到: 】
: =。=并不是说百度的面试官说的都是对的,他也是人,也能犯错,不是吗?
: const不能改变的是C++,但C和C++还是有一些区别的。
: 代码说明了这个问题,嗯。
: ...................
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 17:23:31 2011) 提到:
怎么好像有点不对啊。
代码为:
int x = 9;
const int n = x;
时,
打印的结果是:
9 5 5 5 5 5
这个结果是没有被优化的,
跟你那个加了scanf的结果一样。
这个。。。。
【 在 times123 的大作中提到: 】
: 楼主的代码是有一些特殊的。const n值是编译时可知的。
: 所以,在开启编译器优化选项后,很可能就优化掉了对n这个对象的内存读取。举个不太合适的例子,就像编译器对待define常量类似。
: 但对代码稍微更改之后:
: ...................
☆─────────────────────────────────────☆
times123 (每天写一个helloworld喵) 于 (Mon Apr 11 17:25:34 2011) 提到:
不用存储“9”呀。。。类似define常量的方式=。=
严格的说,应该是C的const变量是可以通过地址来改变的。
【 在 dyrdyr 的大作中提到: 】
: 那加了优化之后,系统把“9”放到哪里去了呢。。另外找了一个地方存放n原来的值?
: 你这么说来,const变量是可以通过地址改变。。那就是百度的那个面试官错了。。
: 【 在 times123 的大作中提到: 】
: ...................
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 17:36:55 2011) 提到:
哦,是呀。。2了。。[em17]
【 在 times123 的大作中提到: 】
: 不用存储“9”呀。。。类似define常量的方式=。=
: 严格的说,应该是C的const变量是可以通过地址来改变的。
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Mon Apr 11 17:38:06 2011) 提到:
在这样的代码中,n值就并不是编译时可知了。你是用一个变量初始化了n。
那自然和我写的scanf的版本的结果一样了。
【 在 dyrdyr (么儿) 的大作中提到: 】
: 怎么好像有点不对啊。
: 代码为:
: int x = 9;
: ...................
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 17:45:41 2011) 提到:
恩,我理解了,大大的谢谢啦。。
【 在 zxsword 的大作中提到: 】
: 在这样的代码中,n值就并不是编译时可知了。你是用一个变量初始化了n。
: 那自然和我写的scanf的版本的结果一样了。
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Mon Apr 11 17:47:40 2011) 提到:
我是C++菜鸟=。=
刚才试了一下。
cpp中:
int *p=&n;这个肯定不能通过,类型不符,编译时错误。
int *p=reinterpret<int *>(&n); 这个依旧不能通过=。=
int *p=(int *)&n;
*p=5;
通过编译,顺利改变n的值。继承自c的语法,更改了const n。
看来,C++中,const变量,也不过是一个普遍的内存对象。const特性,应该是通过编译时的强大的类型检查来保证的。
因为根据C++的语法,是无法获得一个指向const对象的非const指针的。通过编译时的类型检查,可以肯定程序中没有一个非const指针能够指向const对象,也就保证了const特性。
【 在 dyrdyr 的大作中提到: 】
: 受教了。。谢谢。。
: 我说可以,百度的面试官,反问了我一句,“那他为什么还要叫常量呢?”。。呵呵,原来如此。。
: c++中,const不能改变,你测试了?
: ...................
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Mon Apr 11 18:18:14 2011) 提到:
汗,没学过C++。。。谢谢啦。。
【 在 zxsword 的大作中提到: 】
: 我是C++菜鸟=。=
: 刚才试了一下。
: cpp中:
: ...................
☆─────────────────────────────────────☆
cangtian (AlexandreSongBillong) 于 (Mon Apr 11 19:00:03 2011) 提到:
如果是全局变量const int a=5;存在于.rodata中,int *b=&a;*b=6;会提示段错误
☆─────────────────────────────────────☆
astrophile (候鸟) 于 (Mon Apr 11 19:53:08 2011) 提到:
【 在 zxsword 的大作中提到: 】
: 那自然和我写的scanf的版本的结果一样了。
那个times123是马甲?
☆─────────────────────────────────────☆
astrophile (【还我艾神】) 于 (Mon Apr 11 20:13:52 2011) 提到:
【 在 liaowang11 的大作中提到: 】
: 貌似在.rodata里面, 映射到内存中为只读?
: --
如果是全局的const变量,或者同时用static和const修饰,则在.rodata里。而楼主例子里n这个局部变量,是分配在栈上的,即使用const修饰也是可以改变的,只要能编译通过(而c++里编译器会报错)。
☆─────────────────────────────────────☆
renne (歼灭天使 玲) 于 (Mon Apr 11 20:14:50 2011) 提到:
const不能改变的是c++ 这句话也值得商榷吧……
const int n = 9;
int *p = (int*)(&n);
单凭这两句话,有啥c++ c的区别吗……vs2008的结果是n一样改了
【 在 times123 (每天写一个helloworld喵) 的大作中提到: 】
: =。=并不是说百度的面试官说的都是对的,他也是人,也能犯错,不是吗?
: const不能改变的是C++,但C和C++还是有一些区别的。
: 代码说明了这个问题,嗯。
: ...................
☆─────────────────────────────────────☆
renne (歼灭天使 玲) 于 (Mon Apr 11 20:15:17 2011) 提到:
lz这代码vs2008能过……
【 在 astrophile (【还我艾神】) 的大作中提到: 】
: 如果是全局的const变量,或者同时用static和const修饰,则在.rodata里。而楼主例子里n这个局部变量,是分配在栈上的,即使用const修饰也是可以改变的,只要能编译通过(而c++里编译器会报错)。
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Mon Apr 11 20:18:05 2011) 提到:
我不懂C++额。。。
那段代码是用g++编译的,我就当是cpp了=。=对于cpp的认识,目前就局限在将后缀.c改为.cpp的阶段。。。
我是面试被鄙视了好多次的纯C++菜鸟[em9]
【 在 renne 的大作中提到: 】
: const不能改变的是c++ 这句话也值得商榷吧……
: const int n = 9;
: int *p = (int*)(&n);
: ...................
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Mon Apr 11 20:27:18 2011) 提到:
额。。。秘密的小马甲被发现了。。。
【 在 astrophile 的大作中提到: 】
: : 那自然和我写的scanf的版本的结果一样了。
: 那个times123是马甲?
: --
: ...................
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Mon Apr 11 20:47:16 2011) 提到:
突然想到,全局中的const变量,是编译时可知的值呀。那么编译器采用一定的优化技术,是可能被编译器优化掉的。
如果单个的源文件,这个const变量用define常量替换掉,也是毫无问题的。
代码中任何需要用到const常量的地方,都可以在汇编代码中用 立即数 来代替。如此,便省去了一次的内存读操作。
那么const变量的意义在哪里呢?
无责任推测,如果有多个源文件的话,更改一个define常量的话,所有用到的这个define常量的文件,全部需要重新编译。而在.rodata段中的const 变量,并没有define常量这个缺点,只需要重新编译有const变量的那个源文件即可,然后众多需要用到这个const常量的cpp文件,只需要读.rodata段中的一个常量,和之前一模一样。
随意乱想了想,唔。
【 在 astrophile 的大作中提到: 】
: : 貌似在.rodata里面, 映射到内存中为只读?
: : --
: 如果是全局的const变量,或者同时用static和const修饰,则在.rodata里。而楼主例子里n这个局部变量,是分配在栈上的,即使用const修饰也是可以改变的,只要能编译通过(而c++里编译器会报错)。
: ...................
☆─────────────────────────────────────☆
txmm (你被tx啦!) 于 (Mon Apr 11 20:57:39 2011) 提到:
这楼好热啊
☆─────────────────────────────────────☆
astrophile (【还我艾神】) 于 (Mon Apr 11 22:34:24 2011) 提到:
有道理
【 在 zxsword 的大作中提到: 】
: 突然想到,全局中的const变量,是编译时可知的值呀。那么编译器采用一定的优化技术,是可能被编译器优化掉的。
: 如果单个的源文件,这个const变量用define常量替换掉,也是毫无问题的。
: 代码中任何需要用到const常量的地方,都可以在汇编代码中用 立即数 来代替。如此,便省去了一次的内存读操作。
: ...................
☆─────────────────────────────────────☆
ashley1901 (ashley) 于 (Mon Apr 11 22:40:54 2011) 提到:
大牛呀!!!!
☆─────────────────────────────────────☆
zzcc (Binux <足兆叉虫>) 于 (Mon Apr 11 22:49:27 2011) 提到:
所以说这些东西都是“定义”罢了,只要让它看起来是这样就好了,具体是怎么实现的,爱怎么实现就这么实现呗。
虽然不敢说这样理念不好,但是觉得如同python抛弃常量一样,既然能通过变量实现相同的功能,还要常量干嘛?
说常量是为了不能修改?python的做法是用同一的命名区分,比如全大写
如果你真的想改?如果你真的知道自己在干什么,这又何尝不可呢?
即使是第三方调用的时候别人尝试修改,如果他知道他自己在干什么,改坏了库的开发者为什么要为此负责?让他改去吧(因为有命名空间的存在,不存在误修改)
编程语言也是设计出来的,各有各的设计,不敢说哪个好,各有所好吧。。
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Tue Apr 12 12:58:55 2011) 提到:
你这个写法确实是会提示错误;
但是如果这样:
int x;
const int a = x;
int _tmain(int argc, _TCHAR* argv[])
{
x = 9; // x = 0; a = 0; 不知道这个0是随机给的,还是系统默认初始化全局变量为0;
int *p = (int*)(&a); //x = 9;a = 0;
*p = 5; // x = 9; a = 5;
所以,我无责任推测:全局的const初始化为常数的时候,放在.rodata中。 加个条件。
【 在 cangtian 的大作中提到: 】
: 如果是全局变量const int a=5;存在于.rodata中,int *b=&a;*b=6;会提示段错误
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Tue Apr 12 13:08:18 2011) 提到:
我觉得是不是const初始化为常数的时候,才会放到.rodata里头。如果不是,那还是可以改变的,只要编译通过。
【 在 astrophile 的大作中提到: 】
: 如果是全局的const变量,或者同时用static和const修饰,则在.rodata里。而楼主例子里n这个局部变量,是分配在栈上的,即使用const修饰也是可以改变的,只要能编译通过(而c++里编译器会报错)。
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Tue Apr 12 13:19:50 2011) 提到:
全局的const也可以是编译未知的啊。。
比如:
int x;
const int n = x;
ps:弱弱的。。你的那个推测没怎么看明白。。[em17][em17]。。能解释下吗?不好意思。。
【 在 zxsword 的大作中提到: 】
: 突然想到,全局中的const变量,是编译时可知的值呀。那么编译器采用一定的优化技术,是可能被编译器优化掉的。
: 如果单个的源文件,这个const变量用define常量替换掉,也是毫无问题的。
: 代码中任何需要用到const常量的地方,都可以在汇编代码中用 立即数 来代替。如此,便省去了一次的内存读操作。
: ...................
☆─────────────────────────────────────☆
zxsword (小绝) 于 (Tue Apr 12 14:04:47 2011) 提到:
先解释一下我的那些推测,再稍微更正一下。所有的推测,应该建议在已初始化的const变量的基础上。
推测建立在已初始化的const变量和define常量的基础上,比较了define和const变量的意义。
【 在 dyrdyr 的大作中提到: 】
: 全局的const也可以是编译未知的啊。。
: 比如:
: int x;
: ...................
☆─────────────────────────────────────☆
times123 (每天写一个helloworld喵) 于 (Tue Apr 12 14:34:02 2011) 提到:
尝试了一些代码,如下:
int x;
const int n;
const int m=9;
int main()
{
printf("%d",n);
x=9;
int *p=(int *)&m;
// int *p=(int *)&n;
*p=5;
printf("%d",n);
printf("%d",*p);
putchar('\n');
return 0;
}
以elf格式为例,依赖于实现,不同的平台可能会有所不同:
更改m值时,段错误,验证了已初始化的const变量确实是在.rodata中。
而未初始化的变量,并不是在.rodata段中的,而是在.bss中,在程序装入内存时,以0填充这些未初始化的变量,这也就是说默认值为0。
喵了个咪的,未初始化的const变量也是未初始化的变量,也在.bss中。既然在.bss中,只要我们能够获得地址,那么就能更改存储于这个地址的对象了,.bss段是可读可写的。更改n值成功打印5。
综述一下:如果能够获得const对象的指针且该指针的属性不是指向const,而const对象的存储位置并非.rodata,例如栈中或者.bss中,那么const变量的值,是可改的。如果能够获得地址,且该地址不是在只读的内存段,那么就可以改变地址中的值。很多内存错误,也正是来源于此,例如缓冲区溢出,呵呵。
至于楼主的主贴的代码,神奇的现象是由于编译器故做聪明的bug。
哦,还有,这些都是一些琐碎的实现细节,没必要太过深入,语言终归是拿来用的。在实际的扣腚中,简洁明晰的代码,才是王道。
☆─────────────────────────────────────☆
dyrdyr (么儿) 于 (Tue Apr 12 16:24:34 2011) 提到:
大赞。。谢谢啦。。。学习不少。。
可是面试总要问这些变态的问题。。莫有办法啊。。
【 在 times123 的大作中提到: 】
: 尝试了一些代码,如下:
: int x;
: const int n;
: ...................
☆─────────────────────────────────────☆
DrJan ( DrJan) 于 (Tue Apr 12 17:10:06 2011) 提到:
楼主将帖子链接发给面试官 请求一下他指导
或者表明爱学习的态度
或者帮助他进步
= =!
☆─────────────────────────────────────☆
gootyking (『热情一顶乐团』团长|回帖终结者A1) 于 (Tue Apr 12 17:34:06 2011) 提到:
不错啊
【 在 DrJan ( DrJan) 的大作中提到: 】
: 楼主将帖子链接发给面试官 请求一下他指导
: 或者表明爱学习的态度
: 或者帮助他进步
: ...................
☆─────────────────────────────────────☆
xudi5566 (原本无罪) 于 (Tue Apr 12 20:38:02 2011) 提到:
我记得C 和 C++编译器对const的处理是不一样的。貌似在C里面const比较类似于readonly,只读不一定是不可修改的。而C++里的const就一定是常量。楼主的代码确实是可能把原来的 const int m=9; 地址的值改了。在程序的打印里不是从m原来的地址取值。而是直接输出了9.
LZ可以试试在 const int m=9;前面加 violate 修饰符。这样应该就能改变了。
☆─────────────────────────────────────☆
Under (小小黑@北邮刷天下) 于 (Tue Apr 12 22:57:51 2011) 提到:
在c++中 可以用
int * p = const_cast<int *>(&n);
来获得一个指向const对象的非const指针
【 在 zxsword 的大作中提到: 】
: 我是C++菜鸟=。=
: 刚才试了一下。
: cpp中:
: ...................
☆─────────────────────────────────────☆
Under (小小黑@北邮刷天下) 于 (Tue Apr 12 23:12:58 2011) 提到:
是volatile吧。。
【 在 xudi5566 的大作中提到: 】
: 我记得C 和 C++编译器对const的处理是不一样的。貌似在C里面const比较类似于readonly,只读不一定是不可修改的。而C++里的const就一定是常量。楼主的代码确实是可能把原来的 const int m=9; 地址的值改了。在程序的打印里不是从m原来的地址取值。而是直接输出了9.
: LZ可以试试在 const int m=9;前面加 violate 修饰符。这样应该就能改变了。
: --
: ...................
☆─────────────────────────────────────☆
Under (小小黑@北邮刷天下) 于 (Tue Apr 12 23:15:19 2011) 提到:
vs 2005中,const int n;
这句代码无法通过编译
提示必须初始化常量对象 不知道你是怎么通过编译的
【 在 times123 的大作中提到: 】
: 尝试了一些代码,如下:
: int x;
: const int n;
: ...................
☆─────────────────────────────────────☆
astrophile (【还我艾神】) 于 (Wed Apr 13 11:28:07 2011) 提到:
【 在 Under 的大作中提到: 】
: vs 2005中,const int n;
: 这句代码无法通过编译
: 提示必须初始化常量对象 不知道你是怎么通过编译的
: ...................
代码是c的话用gcc可以编译过,但c++的话用g++也会报错。
c和c++里const差别还挺多的。感觉c里面的const主要靠把变量放在.rodata段里实现,而c++里更多的是靠编译器来检查。
☆─────────────────────────────────────☆
zhaojf30 (不明真相的群众) 于 (Wed Apr 13 16:11:58 2011) 提到:
【 在 times123 的大作中提到: 】
: 尝试了一些代码,如下:
: int x;
: const int n;
: ...................
赞大牛,那请问如果const int n是在main()中定义的话,应该在.rodata段中还是在栈中呀?
☆─────────────────────────────────────☆
jokerlee (Jackal The Dire) 于 (Wed Apr 13 22:21:48 2011) 提到:
插一小段
const的只读属性是怎么实现的完全是编译器相关的,运行时的内存模型不是语言标准所约束的
const的作用仅仅是语法上的约定,编译器的义务仅仅是检查的语法上改变常量值的行为
编译器将程序装载时(或者说编译期)就能确定值的常量放到只读段里并不是其义务
所以楼主问“在c语言中是怎么实现其只读特性的?”
答案就是c/c++只保证编译期语法上的只读,不保证也无法保证运行时的只读
(就算是放到只读段里,你也可以通过底层的driver或者hack操作系统改变段属性或者直接操作内存,只要存储介质不是只读的)
顺便感慨一下
现在的一些C/C++面试题对不少人的语言学习造成了的误导(我也被误导了很久)。花大量时间研究内存模型、编译优化等语言的“阴暗角落”。那些东西除了拿来吹nb在基本上一点实用价值都没有,而事实上,一个月之后就会忘得一干二净连nb都吹不了了。。
☆─────────────────────────────────────☆
snowleaves (这个……) 于 (Wed Apr 13 22:45:45 2011) 提到:
c++的const 可以绕过去……
这是一条镜像帖。来源:北邮人论坛 / cpp / #51684同步于 2011/4/26
CPP机器人发帖
[合集] 求大牛:const 在c语言中是怎么实现其只读特性的?
shenlei
2011/4/26镜像同步0 回复
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。