2009-09-23 131 views
2

使用V1.8的z/OS XL C編譯器,使用INFO(ALL)擡高式警告,我得到下面的代碼的4號線以下警告:不允許在類型「const int ** const」和「int **」之間初始化,爲什麼?

WARNING CCN3196 Initialization between types "const int** const" and "int**" 
       is not allowed. 


1 int foo = 0; 
2 int *ptr = &foo; 

3 const int * const fixed_readonly_ptr = ptr; 

4 const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

我不能換我頭部爲什麼我得到這個警告。如果我可以分配一個int指針指向const int(第3行)的const指針,那麼爲什麼我不能將int指針的地址分配給const指針指向const int的指針?我錯過了什麼?

注意上面的代碼是一個瘦身的例子,只是顯示了我在少量代碼中遇到的問題。真正的上下文是,我有一個const指針指向struct(struct s ** const)的指針,並將它作爲參數傳遞給一個函數,它的參數被定義爲const指針指向const struct的const指針(const struct s **常量)。這是因爲該函數不會修改struct中的數據(因此是第一個const),並且它不會修改始終保存傳入地址(因此爲第二個const)的指針參數。指針指向的值可能會改變方式(這就是爲什麼**之間沒有第三個常量)。

+0

帕維爾和查爾斯已經充分說明了爲什麼編譯器警告我。我贊成你們兩位,但是從Charles的角度來看,Charles把它分解了下來(儘管兩個答案都非常相似,並說明了爲什麼會發布警告)。 – 2009-09-24 02:47:50

回答

3

的C規則是,你可以將指針轉換的東西到一個指向const的指針,但是某些東西必須是完全相同的類型,包括鏈下的const和volatile限定。

這一規則的理由是,如果這兩條線的第二被允許:

int *ptr; 

const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

然後這可以被用來打破類型安全性而不鑄造。

const int i = 4; 

// OK, both sides have type const int * 
*fixed_ptr_to_readonly_ptr = &i; 

// the value of fixed_ptr_to_readonly_ptr is still &ptr 
// the value of ptr is now &i; 

*ptr = 5; 

// oops, attempt to change the value of i which is const 
5

這是一種類型的安全違規行爲。考慮這個代碼(我拖着const張望了一下,以明確是否適用於指針或指針對象,但語義這意味着同樣的事情):

int* p = 0; 
int const** pp = &p; // presumably ok 

int const c = 123; 
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue 

*p = 666; // okay, *p is int lvalue 

// wait, so we just changed the value of (const) c above, with no const_cast! 
相關問題