2011-05-11 55 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