const ++在C ++中的行为

时间:2013-12-16 03:13:03

标签: c++ undefined-behavior const-cast

这是我的问题,问题在于评论

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!!!!!!!!!!

谁能告诉我为什么,有些书籍会推荐这些问题? 谢谢!

3 个答案:

答案 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的示例。