作者tinlans ( )
看板C_and_CPP
標題Re: [問題] 請問為什麼 int ** 不能轉成 int const …
時間Wed May 26 04:09:33 2010
※ 引述《photon3108 (John)》之銘言:
: 遇到的問題: (題意請描述清楚)
: int ** ipp;
: int const ** icpp = ipp; // Error
: int const * const * icpcp = ipp; // OK
: 程式跑出來的錯誤結果:
: invalid conversion
: 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux)
: vc++ 2008, gcc 4.4
: 為什麼 line 2 無法編譯,line 3 又可以呢?,謝謝。
簡單的答案是...
C++ 的自動 non-const -> const 規則不會遞迴發生。
以來源 type 的 * 中間沒有出現 const 的最簡單狀況來說,
它並不會飛越第一層非手動加 const 的 * 號 (由右往左看),
過了最後一層 const * 就必須是 exactly match 才可以通過編譯。
int * * * * * ippppp;
int * * * const * const * ipppcpcp = ippppp; // 可以
int * const * * const * const * ipcppcpcp = ippppp; // 不行
int const * * * const * const * icpppcpcp = ippppp; // 不行
int * * const * const * const * ippcpcpcp = ippppp; // 可以
int const * * const * const * const * icppcpcpcp = ippppp; // 不行
這顏色只是標示開始看的起點,
只要有上色的部分都必須跟 RHS type 相對位置的部分是 exactly match。
當然在更複雜的狀況下上面講的也只是必要條件,
還不是充分條件。
不想知道為什麼的就背下這規則就好,
下面可以跳過。
當然它這麼規定必然有原因,
前篇推文裡 softwind 也有講到了,
這邊再講清楚一點。
這問題其實是一個 FAQ:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17
還是看到腦子打結的話也沒關係,
重點在於你需要讓更多 type 來參與你的實驗:
const int i = 0;
int *ip;
int const **icpp = &ip; // 想通過編譯必須用 const_cast<int const **>(&ip)
假設上面三行可以通過編譯,
考慮永遠合法且可編譯的下面這行:
*icpp = &i; // 意思就是 ip = &i;
如果今天 compiler 讓你的 int const **icpp = &ip; 通過編譯,
那麼這就代表它默許了 *icpp = &i; 這種免 const_cast 就能把 const 消去的寫法。
我也知道很多人書看得多,
然後 code 看得多也寫得多以後,
會產生一種某個 type 包含的 const 由少變多必然安全且合法的錯覺,
但是其實並沒有任何一本書講過把 const 數量變多就是對的。
int ** 變成 int const ** 確實表面上看起來 const 變多了應該要會過,
但是讓它過的話卻隱喻了 int const * 可以直接 assign 給 int * 這件事。
意思是如果讓這個不用 const_cast 就合法:
(int const **) = (int **);
就代表這個不用 const_cast 也能合法:
(int *) = (const int *)
其實一開始我也只想回上面這四行,
但是根據以往經驗只回那四行反而會被當成聽不懂問題的番仔,
所以只好開一篇來講。
--
Ling-hua Tseng (
[email protected])
Department of Computer Science, National Tsing-Hua University
Interesting: C++, Compiler, PL/PD, OS, VM, Large-scale software design
Researching: Software pipelining for VLIW architectures
Homepage:
http://www.tinlans.org
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.160.112.117
推 bobhsiao:竟然會有人把你當番仔...?? 05/26 05:29
※ 編輯: tinlans 來自: 118.160.108.141 (05/26 05:39)
→ tinlans:因為不是每個人都看得出關聯性,會認為他問東我答西。 05/26 05:42
→ wudidog:這種用法,這種聰明人,公司會第一個先FIRE吧@@ 05/26 07:32
推 ilovebbs:好複雜<0>..記起來就好XD 05/26 08:55
推 loveme00835:推推~ 05/26 09:44
推 nowar100:Good! 05/26 10:00
推 james732:感謝分享?我對這種東西真的很沒輒 XDDD 05/26 10:09
→ james732: ↑我想打的是! 弄錯了 orz 05/26 10:10
推 loveme00835:兩個符號位置差很遠說!> < 05/26 10:17
推 VictorTom:又有神出現了, 快拜....<(_ _)> 05/26 10:18
推 linjack:獲益良多! 05/26 11:12
推 softwind:最後一段看好久才懂... 05/27 00:04
推 tomap41017:真的是神等級的= =+ 05/29 18:45
推 sdimkk:神 09/19 16:40
推 iamstudent:推薦這篇文章 11/09 01:20