2012-06-15 12 views
3

請參閱以下內容:是否取消引用來自const_cast的指針始終調用未定義的行爲?

struct A 
{ 
    std::string* get() const 
    { 
     //return const_cast<std::string*>(&m_pObj); 
     return &const_cast<A*>(this)->m_pObj; 
    } 

    std::string m_pObj; 
}; 

是提領this UB的const_cast?是否有任何時間解除const_cast結果的指針移除的指針不是調用UB?

(我知道上面的例子是不好的做法,不好的設計,並可以與可變來解決 - 這不是點)

回答

9

是解引用這個UB的const_cast會?是否有任何時間解除const_casting指針的常量而不會調用UB的結果?

並不總是,僅當對象常量(在A實例是const A x;反引用是用來修改的數據。如果它僅用於請參閱它不會是未定義的行爲,如果對象不是const(可能根本不可能,也可能是對非const對象的const引用),它也不會是UB。

3

不,它只是UB引用的對象已被宣佈爲const最初您隨後修改演員獲得的數據(§5.2.11/ 7和§7.1.6.1/ 4)。以下是合法的:

A a; 
a.get()->clear(); 

雖然這不是(並因此UB):

A const a; 
a.get()->clear(); 
+4

只要解除引用不用於*修改*對象,就沒有UB。那就是:'一個const a; std :: cout << * a.get();'很好,但是'a.get() - > clear();'不是。 –

+0

@大衛是的;請參閱更新。哦,我喜歡你的榜樣(' - >清除()')礦(解引用+修改'[0]'),所以我已經偷了它,我希望你不要介意。 –

+0

沒問題:) +1 –

1

號要機智:

5.2.2功能呼叫

5 [注:一個功能可以改變其非const參數的值,但這些變化可以在不影響 參數的值除了參數是引用類型(8.3.2)外;如果參考是一個 常量限定類型,則需要使用const_cast來拋出常量,以便修改參數的值 。如果參數爲常量引用類型,則在需要 (7.1.6,2.14,2.14.5,8.3.4,12.2)時引入一個臨時對象。另外,可以通過指針參數修改非恆定對象 的值。末端注]

然而,

5.2.11常量投

12 [注:一些轉換,其只涉及在CV-資格變化不能使用const_cast會來完成。 例如,函數指針之間的轉換不包括在內,因爲這種轉換會導致 值的使用導致未定義的行爲。出於同樣的原因,指向成員 函數的指針之間的轉換,特別是從指針到const成員函數轉換爲指向非const成員函數的指針之間的轉換不會被涵蓋。 - 注意]

0

編譯器可以在只讀存儲器中自由存儲常量值,它可以自由地假設它在優化程序時不會改變。如果你拋棄了常量,你打破了與編譯器的合約,所以在技術上什麼都可能發生。

實際上,它是一個編譯器做一些事情,會const_cast會-ING被打破相當罕見,但在理論上是可能的。

+0

以前的哪個答案不正確?他們都表示試圖修改一個const對象是未定義的行爲。虛擲常量是完全合法的,總是和修改通過該鑄造結果的對象也是合法的(和明確界定),如果對象本身不是常量。 –

+0

你說得對(我已經刪除了該陳述)。我讀得太快了一點。一切都始於「不」或「不總是」,這似乎是錯誤的,但更好的閱讀,我看他們充分合格。道歉。 –