【问题标题】:Is this const_cast undefined behavior?这是 const_cast 未定义的行为吗?
【发布时间】:2011-08-23 14:45:30
【问题描述】:

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

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

【问题讨论】:

  • 你在问我们! :-) 作为一个有趣的问题,你有这个真实世界的用例吗?和你一样,我一直认为添加 constness 不会破坏任何东西。
  • @unapersson 啊,我刚刚阅读了最后一个 c++0x 规范,结果证明它有答案!我今天和我的同事讨论了这个问题,他将“const”添加到“T”作为“T*”作为插入器适配器,并遇到了一个请求这种隐式转换的问题。
  • 我认为这完全没问题,我在这里没有看到任何危险。
  • 你的意思是暗示传递,例如将double* 转换为采用double const* 的函数会导致UB?如果这是真的,我会很惊讶
  • @ildjarn:一个相关的问题是将转换后的double ** 传递给采用double const** 的函数是否是UB(当该函数使用它时),但您给出的示例不是这是UB。如果这甚至是UB,我的意思是。

标签: c++ const-cast


【解决方案1】:

资质方面,没问题。将每个表达式拆分为一个语句:

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 的新项目符号!
  • @GMan "int const*" 不是更符合 cv 要求的 "int*" 版本。 "int * const" 将是。
  • @Johannes:哦,是的,我现在明白了,我也看到了。这很有趣,因为我认为我现在在回答中提到的项目符号的意图是覆盖新添加的项目符号,但肯定有一个忽略(或者我只是期待它)。你知道这是为什么吗?
  • 感谢您的回答!办理手续:open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#158
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 2011-11-13
  • 2020-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多