2012-12-26 74 views
3

以下代碼的輸出:const的值運行時評估

const int i= 1; 
(int&)i= 2;   // or: const_cast< int&>(i)= 2; 
cout << i << endl; 

是(至少在VS2012)

我的問題:

  • 這種行爲定義?
  • 編譯器是否總是使用定義的常量值?
  • 是否有可能構建一個編譯器使用最新賦值的例子?
+2

確認gcc 4.7.2(Linux)下的結果也是1。如果刪除「const」關鍵字,則結果變爲2(相同的設置)。 – user1284631

回答

3

正如別人所說,行爲是不確定的。

爲了完整性起見,這裏是從標準的報價:除任何類成員聲明可變(7.1.1)可以是MODI音響版,任何企圖

(§7.1.6.1/ 4)在其生存期(3.8)修改一個const對象導致未定義的行爲。 [實施例:

[...]

const int* ciq = new const int (3); // initialized as required 
int* iq = const_cast<int*>(ciq);  // cast required 
*iq = 4;        // undefined: modifies a const object 

]

注意,字對象是本段指的是所有類型的對象,包括簡單的整數,如圖示例–不僅是類對象。

儘管示例指的是一個指針,指向與動態存儲的對象時,段落的文本清楚地表明,這也適用於參考與自動存儲對象以及。

+1

+1用於搜索標準的相關部分。 – user1284631

-1

您正在做一個const_cast,使用類似C-cast operator的IP。使用const_cast不保證任何行爲。

如果你這樣做,它可能工作,或者它可能無法正常工作。

(這不是很好的做法,用C類運營商在C++中,你知道)

4

定義這種行爲?

此代碼的行爲不是由C++標準定義的,因爲它試圖修改一個const對象。

請問編譯器總是使用常量定義的值?

編譯器在這種情況下使用的值取決於實現。 C++標準沒有強制要求。

是否有可能構建一個編譯器將使用最新賦值的值的示例?

有些情況下編譯器會修改值並使用它,但它們不可靠。

7

這完全沒有定義。你不能改變常量的值。

恰巧,編譯器將你的代碼轉換成類似

cout << 1 << endl; 

但該方案也可以同樣會崩潰,或者做別的事情。

如果將警告級別設置得足夠高,編譯器肯定會告訴你它不起作用。

-2

當然可以,但只有當你啓動一個const爲只讀,但不是編譯時常量,如下所示:

int y=1; 
const int i= y; 
(int&)i= 2; 
cout << i << endl; // prints 2 

C++ const關鍵字可以missleading,它要麼一個const或只讀。

+0

-1我不認爲答案可以以「你可以」這個詞開頭。 –

+0

@斯特凡 - 是的,你可以,但前提是...... – StackHeapCollision

+0

做所有的編譯器都表現這種方式? –

3

答案是行爲是未定義的。

我設法建立這個定論例如:

#include <iostream> 

using namespace std; 

int main(){ 

     const int i = 1; 

     int *p=const_cast<int *>(&i); 
     *p = 2; 
     cout << i << endl; 

     cout << *p << endl; 

     cout << &i << endl; 

     cout << p << endl; 

     return 0; 
} 

這下GCC 4.7.2給出:

1 
2 
0x7fffa9b7ddf4 
0x7fffa9b7ddf4 

所以,這就像你有相同的內存地址,因爲它是持有兩個不同的值。

最可能的解釋是,編譯器只是替換常數值與他們的文字值。

+2

不錯的觀察!刪除main()函數的第一行,並要求候選人編寫它以產生給定的輸出可能是一個很好的面試問題... –

+0

@LiorKogan:差不多。由於行爲是不確定/獨立執行的,因此輸出結果可能是2和2,或者被檢查的計算機可能開始哭泣。 :) – user1284631