2013-09-05 15 views
11

指針雖然這編譯:分配指針帶或不帶預選賽

char* p2c; 
const char* p2cc = p2c; //fine 

因爲LHS尖類型有RHS尖類型的所有預選賽,這並不:

char** p2p2c; 
const char** p2p2cc = p2p2c; //fail 

但這種作用:

const char * const * p2cp2cc = p2p2c; //fine 

爲什麼會發生這種情況?

+1

最後一個例子只會編譯C++,但不是在C. – AnT

+0

@AndreyT爲何如此? – emesx

+0

這就是它在C和C++中的方式。這是兩種不同的語言,具有不同的常量正確性規則。在C++中'T **'可以轉換爲'const T * const *'。在C'T **'中可以轉換爲'T * const *',但不能轉換爲'T * const *'。 http://stackoverflow.com/a/5249001/187690 – AnT

回答

7

這不起作用:

char** p2p2c; 
const char** p2p2cc = p2p2c; //fail 

如果允許你將被允許破壞const,正確性:

const int k = 10; 
int *p; 
int **pp = &p; 
int const **kpp = pp;  // Should this be allowed, if so: 
*kpp = &k;    // fine, kpp promises not to change it 
          // yet this does p = &k; 
          // p made no such promise! this is a hidden const_cast! 
*p = 5; 

如果轉讓是允許的,你會這樣設置一個非常量指針(中間值)來引用一個常量值,可能會導致一個不明顯的行爲在非顯而易見的方式看到。通過禁止該操作,類型系統更安全。

但這樣做:

const char * const * p2cp2cc = p2p2c; //fine 

這是好的,由於中間指針是固定的,這是不可能重置中間指針指const對象和打破常量-正確性

+0

爲什麼可以安全地將'char **'轉換爲'char const * const *'? – emesx

+0

@elmes:因爲中間指針也是'const',意味着你不能將它重置爲* wrong *對象。 –

+0

現在似乎很合理,謝謝。 – emesx

-1

cdecl確實有助於這種情況。

const char** p2p2cc = declare p2p2cc as pointer to pointer to const char 

const char * const * p2cp2cc = declare p2cp2cc as pointer to const pointer to const char 

正如你所看到的,第二個版本有內部和外部指針常量,這意味着它也不能修改。第一個版本有INNER指針const和外部非const從而破壞const。

在另一方面,這個工程:

char** const p = p2p2c;