LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 836|回复: 12

问一个const的问题

[复制链接]
发表于 2006-10-24 10:40:11 | 显示全部楼层 |阅读模式
void main(void)
{
   const int a = 4;
   int *p = &a;
   *p = 5;
  printf("%d\n", a);
}
结果居然是5,为什么?a不是只读的吗?gcc4.1编译的
发表于 2006-10-24 11:04:14 | 显示全部楼层
const int *p
回复 支持 反对

使用道具 举报

发表于 2006-10-24 11:43:37 | 显示全部楼层
貌似gcc允许如此只是历史原因,程序不能这么写,结果不可预计
注意
a1.c:4: warning: initialization discards qualifiers from pointer target type


  1. lucida@fancyworld ~/test $ cat a1.c
  2. void main(void)
  3. {
  4. const int a = 4;
  5. int *p = &a;
  6. *p = 5;
  7. printf("a=%d, *p=%d\n", a, *p);
  8. }
  9. lucida@fancyworld ~/test $ gcc a1.c
  10. a1.c: In function ‘main’:
  11. a1.c:4: warning: initialization discards qualifiers from pointer target type
  12. a1.c:6: warning: incompatible implicit declaration of built-in function ‘printf’
  13. a1.c:2: warning: return type of ‘main’ is not ‘int’
  14. lucida@fancyworld ~/test $ ./a.out
  15. a=5, *p=5
  16. lucida@fancyworld ~/test $ gcc a1.c -O2
  17. a1.c: In function ‘main’:
  18. a1.c:4: warning: initialization discards qualifiers from pointer target type
  19. a1.c:6: warning: incompatible implicit declaration of built-in function ‘printf’
  20. a1.c:2: warning: return type of ‘main’ is not ‘int’
  21. lucida@fancyworld ~/test $ ./a.out
  22. a=4, *p=5
复制代码


g++就很好

  1. lucida@fancyworld ~/test $ cat a1.cc
  2. #include <iostream>

  3. using namespace std;

  4. int main(void)
  5. {
  6. const int a = 4;
  7. const int* const p = &a;
  8. *p = 5;
  9. cout<< "%d\n"<< a<<endl;
  10. return 0;
  11. }
  12. lucida@fancyworld ~/test $ gcc a1.cc
  13. a1.cc: In function ‘int main()’:
  14. a1.cc:9: error: assignment of read-only location
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-24 12:00:18 | 显示全部楼层
Post by zhllg
const int *p
用const int *p的话,把p*强制类型转换成int *p一样可以修改a的值
回复 支持 反对

使用道具 举报

发表于 2006-10-24 12:37:33 | 显示全部楼层
according to K&R[1988]:
Appendix A6.6:
A pointer may be converted to another pointer whose type is the same except for the addition or removal of qualifiers of the object type to which the pointer refers. ... If qualifiers are removed, operations on the underlying object remain subject to the qualifiers in its actual declaration

Chapter2.4:
The result is implementation-defined if an attempt is made to change a const
回复 支持 反对

使用道具 举报

发表于 2006-10-24 14:45:00 | 显示全部楼层
Post by jiyongguang
用const int *p的话,把p*强制类型转换成int *p一样可以修改a的值
要是硬改就没辙了
毕竟这个变量是在stack里的,而且C is not a strong typed language,不像c++

所以为了保险,有人建议用gcc -Werror来编译
回复 支持 反对

使用道具 举报

发表于 2006-10-24 15:01:22 | 显示全部楼层
我看一般的程序都是 -Wall
回复 支持 反对

使用道具 举报

发表于 2006-10-24 15:48:40 | 显示全部楼层
[PHP]
// file: a1.cc
#include <iostream>

using namespace std;

int main(void)
{
const int a = 4;
const int *const b = &a;
__asm__ (
        " movl $5, %%ecx \n"
        " movl %%ecx, 0x0(%0) \n"
        : : "r" (b));
cout<<&a<<endl;
cout<<a<<endl;
cout<<b<<endl;
cout<<*b<<endl;
return 0;
}
[/PHP]
gcc a1.cc -lstdc++
./a.out

猜猜会输出什么:)
回复 支持 反对

使用道具 举报

发表于 2006-10-24 16:01:23 | 显示全部楼层
看到输出了没?相同的地址内容确不一样。objdump代码自己看汇编吧,嘻嘻。
回复 支持 反对

使用道具 举报

发表于 2006-10-24 16:50:38 | 显示全部楼层
Post by ahlongxp
我看一般的程序都是 -Wall

-Wall不能启用-Werror
两者无直接联系
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表