这个 const_cast 是否属于未定义行为?

8

我想知道以下是否是未定义行为

// 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是安全的,所以我不确定。


你在问我们! :-) 顺便问一下,你有这个的真实应用场景吗?和你一样,我也一直认为添加const不会破坏任何东西。 - user2100815
@unapersson 啊,我刚刚读了最新的C++0x规范,结果发现它有答案!今天我和同事讨论了这个问题,他在“T*”作为迭代器适配器时给“T”加上了“const”,遇到了一个需要隐式转换的问题。 - Johannes Schaub - litb
我认为这完全没问题,我没有看到任何危险的地方。 - Kiril Kirov
你的意思是暗示传递例如 double* 给一个接受 double const* 的函数会导致未定义行为吗?如果这是真的,我会感到惊讶。 - ildjarn
@ildjarn:一个相关的问题是,将转换后的 double ** 传递给一个接受 double const** 的函数是否会导致 UB(当该函数使用它时),但你提供的示例并不是这种 UB 的结果。如果这确实是 UB 的话,我的意思是。 - Steve Jessop
1个回答

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
关于别名问题,在这里我认为这不是一个问题,或者至少没有意图成为一个问题。
正如您提到的,C++0x允许类似类型(“类似”是指由资格转换产生的类型)的新条目列在了允许访问方法列表中(§3.10)。在C++03中,该条目缺失,但我怀疑允许更多cv限定符访问的条目应该涵盖此内容,但技术上并非如此(即,委员会忽视了这一点)。

@GMan 我的意思是,如果我使用 "int const*" 类型的左值读取 "int*",这不算是别名违规吗?当我今天查看规范时,似乎错过了他们在 C++0x 中将别名规则列表添加了一个新项目的事情! - Johannes Schaub - litb
@GMan "int const*" 不是比 "int*" 更具有cv限定符的版本。"int * const" 才是。 - Johannes Schaub - litb
@Johannes:哦,是的,我现在明白了,我也看到了。这很有趣,因为我认为我在我的回答中提到的项目符号的意图是为了涵盖新添加的项目符号,但可能是有所忽视(或者我对它期望过高)。你知道为什么会这样吗? - GManNickG
1
谢谢你的回答!关于正式事宜:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#158 - Johannes Schaub - litb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接