2012-02-23 80 views
0

我有两段代码,我试图在只读位置修改一个值。其中之一是抛出一个错误。为什么我有时可以修改一个const对象,有时候不是?

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

为什么这个downvote? – 2012-02-23 12:09:03

+0

我没有倒下,但我理解那些人。在你的第一个代码中,你将一个“const”限定变量的地址转换为一个假设它不是的地址。那么你问我们为什么编译器接受这个? – 2012-02-23 12:14:39

回答

4

如果您将编译器警告级别提高,第一个示例也不会编译。


还要注意的是,在第二个例子中,你声明的指针,以解决5,这是不会永远做任何有用的东西。

+0

标准对此有何评论?转换是否允许,或者是实现定义的行为,还是别的吗? – Bazooka 2012-02-23 13:17:30

+0

@Parminder:我不确定;它没有在第6.3节(有效的隐式转换列表)中描述,所以我想这使得它不确定。无论哪种方式,实际上做它都是一个坏主意! – 2012-02-23 13:35:26

2

第一个代码也是不正确的。

您将指针指向int指向定义为const int的对象并对其进行修改。这是一个格式不正确的C程序,但编译器没有检测到错误(可能会给你一个警告)。您可以期待bug出现,因为这一点,特别是如果您打开优化(编译器可以认为该值没有更改)。

的代码仍然编译,因为C是弱类型,并允许不兼容的类型之间的隐式转换(在此情况下,从const int*int*

(注意,这是在C++中的不同,这是更严格的,并会得到你是否尝试过这样的转换编译错误)

+0

“这是一个格式不正确的C程序” - 除非我把我的定义混淆了,它在C中是* not *形式。它只是没有定义的行为,并且在C++中会形成格式。 – 2012-02-23 12:14:41

0

online C99 standard

6.7.3 Type Qualifiers
...
5 If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined. 115)

你试图修改的内容(通过const限定类型定义的对象)到*p(具有非const限定类型的左值),因此行为未定义,其中“未定义”仅表示标准位置不要求编译器执行任何操作尤其是。在这种情况下,编译器将代码翻译为操作“有效”,但不应该依赖于该行为是可重复的。更聪明的编译器(或更严格的警告设置)可能会在此时发布诊断并停止翻译。或者它可能不会。这个问题是在一般情况下检测到的问题,这就是为什么我怀疑这种行为只是未定义。

在第二种情况下,您声明p作为指向const int的指针;你不允许修改*p++(*p)试图去做。

相关问题