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

C++ 是否允许在常量定义的对象上丢弃常量,只要它没有被实际修改?,c++,constants,undefined-behavior,const-cast,C++,Constants,Undefined Behavior,Const Cast,是否允许以下情况: 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 int const_数组[]={42}; int*u公司(bo

是否允许以下情况:

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 int const_数组[]={42};
int*u公司(bool write,int*array){
if(write)数组[0]++;
返回数组[0];
}
int main(){
return-maybe_inc(false,const_cast(const_数组));
}

特别是,只要对象没有被实际修改(如示例中所示),就可以丢弃定义为常量的
常量数组的常量吗?

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

摘自(C++17的最后一稿),第10.1.7.1节[dcl.type.cv]第4段:

除了任何声明为可变(10.1.1)的类成员都可以修改外,在常量对象的生存期(6.8)内修改常量对象的任何尝试都会导致未定义的行为

我的重点。这是来自C++ 17,但是对于C++的所有版本,

都是如此。 如果您查看
const\u cast
一节,会发现

[注意:根据对象的类型,通过指针、左值或指针执行写入操作 由常量转换(丢弃常量限定符76)产生的to数据成员可能会产生未定义的 行为(10.1.7.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;
}
#包括
int main(int argc,char*argv[])
{
常量int arr[]={1,2,3};
int*parr=const_cast(arr);
parr[0]=0;
用于(自动&n:arr)

std::cout确实,只要没有实际执行写操作,您就安全了。
常量转换本身不会导致UB。另请参阅(可能重复?):可能重复有趣的内容,所以当它说“不允许您常量转换实际常量的变量”时,这是错误的(或至少是不精确的)-实际的限制是,不允许修改实际为常量的变量(当然,丢弃常量会移除通常会阻止该操作的护栏)?@BeeOnRope是的。@BeeOnRope证实,这句话是不正确的,你的解释是正确的。事实上,令人惊讶的是,在这个问题上,你能找到多少错误的、经过高度投票的答案。下面是另一个。