【问题标题】:C++17 Standard - Cast away const of staticC++17 标准 - 抛弃静态的 const
【发布时间】:2019-07-11 16:29:21
【问题描述】:

最近我决定深入研究 C++ 标准并检查某些代码 sn-ps 是否定义良好以及在标准中的何处可以找到这些定义。由于标准很难正确(尤其是如果您不习惯),我想验证我的假设是否正确。

我遇到了以下示例(这显然是个坏主意)。它编译得很好(使用 g++ 8.2.1),但在执行期间 SEGFAULTs:

#include <iostream>

static const int staticInt = 23;

int main () {
    int &localInt = const_cast<int &>(staticInt);
    localInt = 11;
    std::cout << staticInt << std::endl;
    return 0;
}

所以,我搜索了标准(我使用 open-std btw 上的工作草案)并找到了第 6.8.10 段:

在存储中创建一个新对象,该对象具有静态、线程或自动的 const 完整对象 存储持续时间占用,或在此类 const 对象在其生命周期之前曾经占用的存储空间内 结束,导致未定义的行为。

我是对的,这一段适用于给定的例子吗?如果不是,我还应该去哪里看?

【问题讨论】:

  • 你的代码没有在staticInt的存储中创建一个新对象,所以它不可能应用。
  • 与此问题相关的部分是关于const 变量的部分。您尝试修改 const 变量,这会导致 UB。故事结局。它是static 或在全局范围内,或者您使用对变量的引用或引用在不同的范围内是无关紧要的。
  • @molbdnilo 普通类型的赋值在某些情况下确实会创建一个新对象。不知道这些情况应该是什么......

标签: c++ language-lawyer c++17 const-cast


【解决方案1】:

这是未定义的行为,因为在使用 const_cast 之后尝试修改 const 变量。

来自 n4659 的引文,C++17 的最终工作草案。 本案相关段落为:

8.2.11 常量转换 [expr.const.cast]
...
6 [ 注意:根据对象的类型,通过指针、左值或指向数据成员的指针的写操作由 const_cast 产生,它抛弃了 const 限定符可能会产生未定义的行为. ——尾注]

这部分也与const 对象相关:

10.1.7.1 cv 限定符[dcl.type.cv]
...
4 除了可以修改声明为 mutable 的任何类成员外,任何在其生命周期内修改 const 对象的尝试都会导致未定义的行为。

【讨论】:

  • 嗯,这似乎更合理。谢谢你的回答。
  • 我认为7.1.7.1p4 更明确:...., any attempt to modify a const object during its lifetime results in undefined behavior.
  • @KamilCuk:刚刚添加了那个。感谢您提及。
  • 我会交换你的两个引号。 [dcl.type.cv]/4 是 OP 的 sn-p 是 UB 的原因,[expr.const.cast]/6 是“也相关”;)
  • @YSC:我也想这样做,但后来我意识到如果没有const_cast,代码甚至无法编译。所以我先解决了这个问题。
猜你喜欢
  • 2018-06-02
  • 1970-01-01
  • 2020-08-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 2012-07-05
  • 2013-05-06
相关资源
最近更新 更多