我有两段代码,我试图修改只读位置的值。其中一个是抛出错误。
1stcode.c
void main()
{
int const k=9;
int *p=&k;
*p=10;
printf("%d",k);
}
2ndcode.c
void main()
{
int const * p=5;
printf("%d",++(*p));
}
这里1stcode.c
允许我简单地修改只读内存位置,但2ndcode.c
会抛出错误:
error: increment of read-only location '*p'
为什么两个位置都是只读的呢?
答案 0 :(得分:4)
如果您将编译器警告级别提高,第一个示例也将无法编译。
另请注意,在第二个示例中,您将声明一个指向地址5的指针,这不会做任何有用的事情。
答案 1 :(得分:2)
第一个代码也不正确。
指向int
的指针指向定义为const int
的对象并修改它。这是一个格式错误的C程序,但编译器没有检测到错误(好吧,它可能会给你一个警告)。您可能会因此而出现错误,特别是如果您启用优化(编译器可以假设该值未更改)。
代码仍在编译,因为C是弱类型的,允许在不兼容的类型之间进行隐式转换(在这种情况下,从const int*
到int*
。
(请注意,这在C ++中是不同的,这是更严格的,如果您尝试进行此类转换,则会出现编译错误。)
答案 2 :(得分:0)
6.7.3类型限定词
...
5如果尝试通过使用修改使用const限定类型定义的对象 如果是非const限定类型的左值,则行为未定义。如果是尝试 通过使用左值来引用用volatile限定类型定义的对象 对于非易失性限定类型,行为未定义。 115)
您正在尝试通过k
(具有非const限定类型的左值)修改*p
(使用const限定类型定义的对象)的内容,因此行为未定义,其中“undefined”仅表示标准不要求编译器特别做任何事情。在这种情况下,编译器以操作“工作”的方式转换代码,但您不应该依赖该行为是可重复的。更智能的编译器(或更严格的警告设置)可能会在此时发出诊断并停止翻译。或者它可能不会。这个问题是在一般情况下检测的错误,这就是为什么我怀疑行为只是未定义的原因。
在第二种情况下,您已将p
声明为指向const int
的指针;您不能修改*p
,++(*p)
尝试执行此操作。