这是我的问题,问题在评论中
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!!!!!!!!!!
谁能告诉我为什么,推荐一些书籍说明这些问题?谢谢!
这是我的问题,问题在评论中
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!!!!!!!!!!
谁能告诉我为什么,推荐一些书籍说明这些问题?谢谢!
正如所写的那样,您这样做的方式是未定义的行为。如果您想以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,这就是您发布的代码所做的。(至少正如我多次向我解释过的那样)。
C++ 标准部分草案7.1.6.1
cv-qualifiers第4 段说:
[...]任何在 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
编译器在欺骗你,因为这(编辑:你在上面使用它的方式。)是明确未定义的行为。当它看到与语句a
在同一范围内定义的常量cout
时,很可能甚至都不会费心查看内存。
你可以做一个更人为的例子来欺骗你的编译器,但是下面的修改至少给了我你在 gcc 中想要的结果:
volatile const int a = 5;
为了澄清,并非所有 const_cast 使用都是未定义的行为,请参阅 WhozCraig 的示例。