相同的地址显示了使用g ++编译器的const变量的不同值
以下代码显示了使用const
变量i
时使用gcc和g ++的不同输出。 i
的地址和ptr
值是相同的,但是在通过打印i
值和ptr
derefrencing值访问该地址时,我得到i
值为5
,g ++为10
,gcc为10
。
g ++如何在内存中保存const变量?
#include int main() { const int i =5; int *ptr =(int*)&i; *ptr = 10; printf("\n %u and %u and %d and %d \n",&i,ptr,i,*ptr); return 0; }
您正在修改const
限定对象。 这在C中是不允许的(“未定义的行为”)。 任何事情都可能发生。
例子:
- 编译器可以将
i
放入只读内存。 写入*ptr
会导致程序崩溃。 - 它可以把它放入可写的内存中,你只会看到10。
- 它可以将它放入可写的内存中,但用5号替换对
i
的所有读访问(你答应它是const
,不是吗?)。
我猜C编译器选择2而C ++编译器选择3。
其他人评论了代码正在做什么的“未定义”性质。 但是要解释这是如何发生的,编译器完全有可能应用了优化, i
的运行时值永远不会传递给printf
,而是用常量5
替换i
。 你确实声明它是const
所以它不应该改变。
它可能在内存中,也可能被硬编码到您的可执行文件中。 它是const
; 编译器可以对其执行积极的优化。
这就是您不能修改它的原因 。
您可以取消引用/转换const
为非成本和覆盖,但行为未定义。
由于行为未定义,您可能会得到任何结果,您不应该质疑为什么,如何等等。
一旦编译器获知你的变量是const
,就可以很好地将这个变量保存在RO内存中和/或用硬编码的值替换这个变量的出现。 除非在代码中询问其地址,否则C ++编译器可能会选择不将内存分配给const
变量。
经验法则是,决定是否要更改变量并相应地使其成为const
。