作者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
1F:推 bobhsiao:竟然会有人把你当番仔...?? 05/26 05:29
※ 编辑: tinlans 来自: 118.160.108.141 (05/26 05:39)
2F:→ tinlans:因为不是每个人都看得出关联性,会认为他问东我答西。 05/26 05:42
3F:→ wudidog:这种用法,这种聪明人,公司会第一个先FIRE吧@@ 05/26 07:32
4F:推 ilovebbs:好复杂<0>..记起来就好XD 05/26 08:55
5F:推 loveme00835:推推~ 05/26 09:44
6F:推 nowar100:Good! 05/26 10:00
7F:推 james732:感谢分享?我对这种东西真的很没辄 XDDD 05/26 10:09
8F:→ james732: ↑我想打的是! 弄错了 orz 05/26 10:10
9F:推 loveme00835:两个符号位置差很远说!> < 05/26 10:17
10F:推 VictorTom:又有神出现了, 快拜....<(_ _)> 05/26 10:18
11F:推 linjack:获益良多! 05/26 11:12
12F:推 softwind:最後一段看好久才懂... 05/27 00:04
13F:推 tomap41017:真的是神等级的= =+ 05/29 18:45
14F:推 sdimkk:神 09/19 16:40
15F:推 iamstudent:推荐这篇文章 11/09 01:20