C ++ - 使用地址解释来转换const

时间:2013-04-24 13:53:04

标签: c++ casting const

我在c ++中输入以下代码 我想做一个const变量并改变它, 这是代码:

#include <iostream>
using namespace std;
int main()
{
    int const a = 5;
    int* ptr = (int*)&a;
    *ptr = 10;
    cout<<"a is : "<< a << endl;

    system("pause");
}

这段代码通过编译器,我希望程序打印一个屏幕10,
但屏幕上的结果是5.
当我运行调试器时,&amp; a中的内存已经像我预期的那样被更改为10 知道为什么吗?

2 个答案:

答案 0 :(得分:3)

首先,这是未定义的行为。不要这样做。其次,当你打印出&a时,编译器优化了实际查看a的内存,因为你告诉编译器a永远不会改变(你说它是const) 。所以它实际上变成了......

cout << "a is : "<<5 << endl;

答案 1 :(得分:3)

您正在使用相关代码调用未定义的行为,尝试通过丢弃const来更改声明为const的变量是不允许的(除非 const变量确实是一个引用到一个不是const)的变量。

对您的结果有一个合理且极有可能的解释是编译器知道a的值不应该改变,因此它几乎可以用{{a取代所有出现的5 1}}。即。 “查找”已经过优化。

为什么要查看a的地址,以便在声明为5时将其读取为值?


让我们来看看编译器可能将代码段变成什么指令

Foo.cpp中

void func (int)
{
  /* ... */
}

int
main (int argc, char *argv[])
{
  const int a = 10; 

  int * p     = &const_cast<int&> (a);

  *p = 20; 

  func (a);
}

main

提供的g++ -S foo.cpp汇编说明
main:
.LFB1:
  .cfi_startproc
  pushq %rbp
  .cfi_def_cfa_offset 16
  .cfi_offset 6, -16 
  movq  %rsp, %rbp
  .cfi_def_cfa_register 6
  subq  $32, %rsp
  movl  %edi, -20(%rbp)
  movq  %rsi, -32(%rbp)
  movl  $10, -12(%rbp)
  leaq  -12(%rbp), %rax
  movq  %rax, -8(%rbp)
  movq  -8(%rbp), %rax # store the adress of `a` in %rax
  movl  $20, (%rax)    # store 20 at the location pointed to by %rax  (ie. &a)
  movl  $10, %edi      # put 10 in register %edi (placeholder for first argument to function)
                       # # notice how the value is not read from `a`
                       # # but is a constant
  call  _Z4funci       # call `func`
  movl  $0, %eax
  leave
  .cfi_def_cfa 7, 8
  ret 
  .cfi_endproc

如上所示,20的值确实放在%rax中存储的地址,其中(%rax)包含amovl $20, (%rax))的地址,但我们调用void func (int)的论点是常数10movl $10, %edi)。

如前所述;编译器假定a的值不会改变,而不是每次使用a时读取内存位置,而是用常量值10替换它。