是否允许以下内容:
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));
}
特别是,只要示例中没有实际修改对象,就可以放弃{<1>}定义为常量的const_array
的常量性吗?
答案 0 :(得分:10)
是的。这是完全合法的。 (这很危险,但是它是合法的。)如果(尝试)修改一个声明为const的对象,则行为是不确定的。
摘自n4659(这是C ++ 17的最新草案),第10.1.7.1节[dcl.type.cv]第4段:
除了可以声明任何声明为可变的类成员(10.1.1)之外,任何在其生存期(6.8)内修改const对象的尝试都会导致未定义的行为
我的重点。那是从C ++ 17开始的,但是对于所有版本的C ++都是如此。
如果您查看const_cast
上的部分,请注意
[注意:根据对象的类型,通过指针,左值或指针进行写操作 丢弃const-qualifier76的const_cast生成的数据成员可能会产生未定义的 行为(10.1.7.1)。 —尾注]
注释不是规范性的,但这强烈意味着获得非const引用或指向const对象的指针是合法的。不允许写。
答案 1 :(得分:-2)
如果编译,则允许它。但这并不意味着它是合法的。
#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++
编译器中编译。它也可以毫无问题地运行。但是上面的代码实际上是未定义的行为。