这是我的问题,问题在于评论
const int a = 5;
const_cast<int&>(a)=7; //throw over const attribute in a,and assign to 7
std::cout<<a<<std::endl; //why still out put 5!!!!!!!!!!
谁能告诉我为什么,有些书籍会推荐这些问题? 谢谢!
答案 0 :(得分:7)
按照你所写的方式,这是未定义的行为。如果您想以定义的方式查看const_cast<>
的效果:
int a = 5; // note: not const. regular object.
const int& cref = a; // const-reference to same object.
cref = 7; // illegal. cref is a const reference.
const_cast<int&>(cref) = 7; // legal. the original object a is not const.
仅这是定义行为的原因是由于原始变量a
的非常量性质。你不能采用一个完整的const 对象并简单地抛弃const-ness,这就是你发布的代码所做的事情。 (至少已经多次向我解释过了。)
答案 1 :(得分:3)
draft C++ standard部分7.1.6.1
cv-qualifiers 段 4 说:
[...]任何在生命周期内修改const对象的尝试(3.8)都会导致undefined behavior
所以任何行为都是可能的,但你不应该这样做,你绝对不能依赖这种行为。当然, const_cast 确实具有有效用途,因为Is const_cast safe?中接受的答案是:
const_cast只有在你输出一个最初非常量的变量时才是安全的。[...]
我们可以看到一种方式,您看到的结果可能会发生live example gcc 4.8.1
5
没有任何优化只是使用值movl $7, (%rax)
movl $5, %esi
movl $_ZSt4cout, %edi
而不是读取当前值:
non const
在movl $7, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
movl $_ZSt4cout, %edi
案例中我们会看到类似的内容:
{{1}}
答案 2 :(得分:1)
编译器欺骗了你,因为这(编辑:你在上面使用它的方式完全正确。)是显式未定义的行为。当它看到a
常量定义在与cout
语句相同的范围内时,它甚至不会费心去查看内存。
你可以制作一个更加人为的例子来欺骗你的编译器,但是下面的修改至少给了你想要的结果:
volatile const int a = 5;
为了澄清,并非所有const_cast用法都是未定义的行为,请参阅WhozCraig的示例。