int main()
{
const int maxint=100;//The program will crash if this line is put outside the main
int &msg=const_cast<int&>(maxint);
msg=200;
cout<<"max:"<<msg<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果'const int maxint = 100;',该函数将运行正常.定义被放在main函数内但崩溃并弹出一条错误消息,如果放在外面则说"Access Violation".
有人说这是某种"未定义的行为",我想知道确切的答案以及如何安全地使用const转换?
它们是正确的,它是未定义的行为.你不允许修改const变量的值,这样就有可能丢掉const某些东西:你最好知道它不是真的const.
编译器,看到maxint的const,应该永远不会被修改,甚至没有给它一个地址.maxint如果认为合适,它可以替换100的所有用途.另外,正如Matteo Italia指出的那样,它可能只是将常量放入只读内存的一部分,这可能就是你正在发生的事情.这就是为什么修改它会产生不确定的行为.
你可以安全地抛弃const变量的唯一方法是,如果变量实际上不是const,但是const限定符被添加到非const变量,如下所示:
int f(const int& x) {
int& nonconst = const_cast<int&>(x);
++nonconst;
}
int blah = 523;
f(blah); // this is safe
const int constblah = 123;
f(constblah); // this is undefined behaviour
Run Code Online (Sandbox Code Playgroud)
想想这个完美编译的例子:
int f(const int& x) {
int& nonconst = const_cast<int&>(x);
++nonconst;
}
int main() {
f(4); // incrementing a number literal???
}
Run Code Online (Sandbox Code Playgroud)
您可以看到如何使用const_cast非常危险,因为无法实际判断变量是否最初const.你应该尽可能避免使用const_cast(使用函数,只是不接受const参数).
修改一个对象const(可变成员除外)会导致未定义的行为(来自C++ 03标准):
7.1.5.1/4"cv-qualifiers"
除了可以修改声明为mutable(7.1.1)的任何类成员之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为.
上述未定义的行为在标准的部分中特别指出const_cast:
5.2.11/7"Const cast"
[注意:根据对象的类型,通过指针,左值或指向数据成员的指针的写入操作可能会产生未定义的行为(7.1.5.1).]
因此,如果你有一个const实际上不是对象的指针或引用const,你可以写入该对象(通过抛弃constness),但如果对象确实是,则不允许const.
例如,允许编译器将const对象放在只读存储中.它没有必要,显然不适用于没有崩溃的测试代码.