【问题标题】:Is it allowed to cast away const on a const-defined object as long as it is not actually modified?只要未实际修改,是否允许在 const 定义的对象上丢弃 const?
【发布时间】:2019-06-27 11:47:48
【问题描述】:

是否允许:

const int const_array[] = { 42 };

int maybe_inc(bool write, int* array) {
  if (write) array[0]++;
  return array[0];
}

int main() {
  return maybe_inc(false, const_cast<int *>(const_array));
}

特别是,只要对象没有像示例中那样实际修改,是否可以抛弃const_array 的常量,它被定义为常量? p>

【问题讨论】:

标签: c++ constants undefined-behavior const-cast


【解决方案1】:

如果它编译,那么它是允许的。但这并不意味着,它是合法的。

#include <iostream>

int main(int argc, char *argv[]) 
{
    const int arr[] = {1, 2, 3};
    int* parr = const_cast<int*>(arr);
    parr[0] = 0;
    for(auto& n : arr)
        std::cout << n << std::endl;
}

以上代码在 Ubuntu 20.04 g++ 编译器中编译。它也可以毫无问题地运行。但上面的代码实际上是未定义的行为

【讨论】:

    【解决方案2】:

    是的。这是完全合法的。 (这是危险的,但它是合法的。)如果您(尝试)修改声明为 const 的对象,则行为未定义。

    来自n4659(这是 C++17 的最后一个草案),第 10.1.7.1 节 [dcl.type.cv] 第 4 段:

    除了可以修改任何声明为 mutable (10.1.1) 的类成员外,任何在 const 对象的生命周期 (6.8) 期间修改它的尝试都会导致未定义的行为

    我的重点。这是从 C++17 开始的,但所有版本的 C++ 都是如此。

    如果你查看const_cast 的部分,有一条说明

    [ 注意:根据对象的类型,通过指针、左值或指针进行写操作 从 const_cast 产生的数据成员丢弃 const-qualifier76 可能会产生 undefined 行为 (10.1.7.1)。 ——尾注]

    注释不是规范的,但这强烈暗示获取非常量引用或指向 const 对象的指针是合法的。是不允许写入。

    【讨论】:

    • 很有趣,所以this answer 说“你不允许 const_cast 实际上是 const 的变量”时是错误的(或者至少是不精确的)。 - 实际的限制是您不允许 修改 实际上是 const 的变量(当然抛弃 const 会删除通常会阻止这种情况的护栏)?
    • @BeeOnRope 是的。
    • @BeeOnRope 确认,该引用不正确,您的解释是正确的。
    • 在这个主题上能找到多少错误的高票数答案真是令人惊讶。这是另一个。 stackoverflow.com/questions/357600/is-const-cast-safe
    猜你喜欢
    • 2020-10-14
    • 1970-01-01
    • 2010-12-05
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    相关资源
    最近更新 更多