const_cast 与可变和未定义的行为

asi*_*mes 1 c++ mutable const-cast undefined-behavior

编辑:我在这里编辑了代码,不使用指针,因为有太多不相关的注释

#include <iostream>

struct Foo {
    Foo(const int a) : total(a) {}

    int       index = 0;
    const int total;
};

struct Bar {
    Bar(const int a) : total(a) {}

    mutable int index = 0;
    const int   total;
};

int main() {
    const Foo foo(3);
    for (
        ;
        foo.index < foo.total;
        const_cast<Foo*>(&foo)->index++ // 1. Undefined behavior because foo is const
    )
        std::cout << "Foo " << foo.index << std::endl;

    const Bar bar(3);
    for (
        ;
        bar.index < bar.total;
        bar.index++ // 2. Not undefined behavior because of mutable?
    )
        std::cout << "Bar " << bar.index << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,标有 的行// 1. Undefined behavior because foo is const是未定义的行为,因为foo它是一个const对象并且const_cast无论如何都被用来修改该对象

但是我不确定是否存在与标记为 的行相关的任何可能的未定义行为// 2. Not undefined behavior because of mutable?。它本质上是通过使用实现相同的结果mutable它本质上是通过使用而不是const_cast

我的问题是,是否存在const带有成员的对象mutable可能导致未定义行为的情况

小智 7

字段mutable永远不是 const,因此永远不能使用 const_cast 调用 UB。这不是相同的行为,因为理论上#1 可以将索引放置在 ROM 中

  • @asimes const 对象的“可变”成员子对象本身不是 const 对象,并且 const 对象的特殊规则(例如不允许修改它)不适用于它。包含对象和其他不可变子对象仍然是 const 对象,因此不能被修改。(请参阅标准中的 https://eel.is/c++draft/basic.type.qualifier#1.1。) (3认同)
  • @asimes 只是那个成员。当它是“mutable”时,它就不是“const”。编译器不会假设它是 `const` (2认同)