2011-05-11 81 views
7

我想知道下面是不確定的行爲這是const_cast未定義的行爲?

// Case 1: 
int *p = 0; 
int const *q = *const_cast<int const* const*>(&p); 

// Case 2: (I think this is the same) 
int *p = 0; 
int const *const *pp = &p; 
int const *q = *pp; 

通過讀取int*就好像它是一個int const*這個不確定的行爲?我認爲這是未定義的行爲,但我以前認爲一般只添加const是安全的,所以我不確定。

+0

你在問我們! :-)作爲一個利益的問題,你有這樣的真實世界的用例嗎?和你一樣,我一直認爲增加常量不能破壞任何東西。 – 2011-05-11 20:06:24

+0

@unapersson啊我剛剛讀了最後一個C++ 0x規範,結果證明它有答案!我今天正在和我的同事討論這個問題,他爲「T *」添加了「const」作爲interator適配器,並遇到了一個問題,要求進行這種隱式轉換。 – 2011-05-11 20:08:12

+0

我覺得這很好,我在這裏看不到任何危險。 – 2011-05-11 20:10:07

回答

5

資質方面,這很好。與分割成語句中的每個表達式:

int *p = 0; // ok 
int **addrp = &p; // ok 
int const *const *caddrq = addrp; // ok, qualification conv. according to §4.4/4 
int const *q = *caddrq; // ok 

注意的const_cast(§5.2.11/ 3)的規則是相同的那些合格的轉換的,但沒有被要求在資格單調增加。在你的情況下,因爲你只是添加資格,const_cast是不必要的。


關於鋸齒,我不認爲這是一個問題,在這裏,或者至少它不打算是。

就像你提到的那樣,允許訪問方法(§3.10)的C++ 0x列表中有一個新的項目符號,它允許類似的類型(類似的類型是從資格轉換中產生的類型)。在缺少子彈的C++ 03中,但我懷疑關於允許更多符合cv限定的訪問的子彈是爲了掩蓋這一點,但從技術上講並非如此(即委託人忽略了這一點)。

+0

(當然,因爲你問我可能是錯的。) – GManNickG 2011-05-11 20:10:54

+0

@GMan我的意思是,如果我通過類型爲「int const *」的左值讀取「int *」,這是不是混疊違規?當我今天看到spec時,我似乎錯過了他們爲C++ 0x添加了一個新的項目符號到別名規則列表! – 2011-05-11 20:14:15

+0

@GMan「int const *」不是更多的「int *」的cv限定版本。 「int * const」會。 – 2011-05-11 20:23:46