2012-02-23 73 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)試圖去做。

相關問題