前几天,一位C ++培训师告诉我,“const”只在编译时(静态)有意义,因此在运行时没有影响......但是当我测试这个例子时:
const int x = 5;
int * px = const_cast<int*>(&x);
*px = 10;
std::cout << "x = " << x <<std::endl; // x = 5 ???
x不是用10修改的!然而,如果我们使用指针,这个例子按预期工作:
const int * x = new int(5);
int * px = const_cast<int*>(x);
*px = 10;
std::cout << "x = " << *x <<std::endl; // x = 10
那么,这个C ++培训师错了吗?
答案 0 :(得分:10)
通过const T
修改const_cast
的未定义行为。这允许编译器在假设从未发生过的情况下优化代码。在您的第一个代码示例中,编译器可能在调用5
期间在代码中插入了文字operator<<
。
您的第二个示例已完全明确定义,因为x
实际上指的是int
,不是 a const int
。在这种情况下,抛弃const
就好了。
答案 1 :(得分:3)
首先删除声明为const
的变量的常量,这是未定义的行为。
删除const const
的const指针或对非const变量的引用很好,但不推荐。
我想不出任何实际派生自C ++ const
关键字的汇编指令,所以我猜这部分没有“运行时”操作,但是,将变量声明为const
可能会通知编译器将变量存储在数据段中,或者直接对汇编代码中的值进行硬编码,而无需分配其neccesery空间(在堆栈等)。因此,从const变量派生的汇编代码可能看起来与从可变变量派生的汇编代码完全不同。
答案 2 :(得分:0)
正如其他评论者提到的那样,您通过修改最初声明为const的对象从编译器调用了未定义的行为。 const_castr旨在剥离获取的 constness,就像对象被声明为可修改,但是传递到某个地方const
引用。
你的代码实际上也与其他东西接壤,这也是非常危险的。你有没有像这样定义你的变量:
static const int x = 5;
您的应用程序可能会崩溃。这样做的原因是这样声明的变量很可能被放在可执行文件的只读段中,对这样的段的修改会导致硬件中止。