Looks like the compiler is optimizing
printf("IAMCONST %d
",IAMCONST);
into
printf("IAMCONST %d
",3);
since you said that IAMCONST
is a const int
.
But since you're taking the address of IAMCONST
, it has to actually be located on the stack somewhere, and the const
ness can't be enforced, so the memory at that location (*pTOCONST
) is mutable after all.
In short: you casted away the const
ness, don't do that. Poor, defenseless C...
Addendum
Using GCC for x86, with -O0
(no optimizations), the generated assembly
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl $3, -12(%ebp)
leal -12(%ebp), %eax
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
movl $7, (%eax)
movl -12(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl -8(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $.LC1, (%esp)
call printf
copies from *(bp-12)
on the stack to printf
's arguments. However, using -O1
(as well as -Os
, -O2
, -O3
, and other optimization levels),
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $20, %esp
movl $3, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $7, 4(%esp)
movl $.LC1, (%esp)
call printf
you can clearly see that the constant 3
is used instead.
If you are using Visual Studio's CL.EXE
, /Od
disables optimization. This varies from compiler to compiler.
Be warned that the C specification allows the C compiler to assume that the target of any int *
pointer never overlaps the memory location of a const int
, so you really shouldn't be doing this at all if you want predictable behavior.