我在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
知道为什么吗?
答案 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)
包含a
(movl $20, (%rax)
)的地址,但我们调用void func (int)
的论点是常数10
(movl $10, %edi
)。
如前所述;编译器假定a
的值不会改变,而不是每次使用a
时读取内存位置,而是用常量值10
替换它。