6

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

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

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

4

3 回答 3

10

正如所写的那样,您这样做的方式是未定义的行为。如果您想以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,这就是您发布的代码所做的。(至少正如我多次向我解释过的那样)。

于 2013-12-16T03:35:08.367 回答
4

C++ 标准部分草案7.1.6.1 cv-qualifiers4 段说:

[...]任何在 const 对象的生命周期 (3.8) 期间对其进行修改的尝试都会导致未定义的行为

所以任何行为都是可能的,但你不应该这样做,你绝对不能依赖这种行为。当然const_cast确实有作为const_cast 安全吗?说:

const_cast 仅在您强制转换最初是非 const 的变量时才是安全的。[...]

我们可以从这个实时示例中看到您看到的结果的一种方式,即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
于 2013-12-16T03:21:15.450 回答
1

编译器在欺骗你,因为这(编辑:你在上面使用它的方式。)是明确未定义的行为。当它看到与语句a在同一范围内定义的常量cout时,很可能甚至都不会费心查看内存。

你可以做一个更人为的例子来欺骗你的编译器,但是下面的修改至少给了我你在 gcc 中想要的结果:

volatile const int a = 5;

为了澄清,并非所有 const_cast 使用都是未定义的行为,请参阅 WhozCraig 的示例。

于 2013-12-16T03:20:12.800 回答