是否允许在 const 定义的对象上丢弃 const 只要它实际上没有被修改?

Is it allowed to cast away const on a const-defined object as long as it is not actually modified?

是否允许以下​​内容:

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 的常量性,它被 定义 为常量,只要对象没有实际修改,如示例所示?

是的。这是完全合法的。 (这很危险,但它是合法的。)如果你(试图)修改一个声明为 const 的对象,那么行为是未定义的。

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

Except that any class member declared mutable (10.1.1) can be modified, any attempt to modify a const object during its lifetime (6.8) results in undefined behavior

我的重点。这是来自 C++17,但所有版本的 C++ 都是如此。

如果您查看有关 const_cast 的部分,会注意到

[ Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a const-qualifier76 may produce undefined behavior (10.1.7.1). — end note ]

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

如果编译通过,则允许。但是不代表,是合法的。

#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++ 编译器中编译。它也可以毫无问题地运行。但是上面的代码实际上是undefined behavior.