Generally, especially when optimization is turned on, a compiler will attempt to make constants as efficient as possible. For example, if you write x = 3*4 + 5, the compiler would reduce this to 17 at compile time rather than putting 3, 4, and 5 in the compiled program.
Small constants that are used directly are often encoded into immediate fields of instructions.
If the compiler cannot put a constant into the immediate field of an instruction, it will generally seek to store it in read-only memory.
However, the example you give makes that difficult for the compiler. The code in your example:
- Defines a
const object inside a routine (as opposed to at file scope).
- Takes the address of the object.
If you merely defined a const object and never took its address, the compiler could store the constant in the read-only data section.
However, since you take the address of the object, there is a problem. Routines can be called recursively. (Your program does not call main recursively, but the compiler is designed to support recursive calls, so the issues discussed here apply to its design.) Whenever a routine is called recursively, new instances of the objects defined in it must be created (in the C model of computation). If the address of a const object were not taken, the compiler could optimize this by using the same read-only memory for all instances of the object—since their values never change, nobody could tell they were just one instance instead of multiple copies.
However, different instances of an object can be distinguished by their addresses. Since you take the address of the object, the compiler wants to create actual different instances of it. That is difficult to do in read-only memory. Programs do not normally maintain a stack for read-only memory, so the compiler does not have a convenient way to track the multiple instances that would have to be created for objects in read-only memory. (It would be difficult to maintain a stack for read-only memory. If what is on the stack can be different at different times, then the memory for that stack has to change. So, even if only read-only objects are on a stack, the stack itself cannot be read-only.)
So, in this case, the compiler places your const object on the regular stack.
Of course, that is not a behavior you may rely on. Attempting to change the value of an object that is defined const has behavior not defined by the C standard. Even though it appears to “work” in this case, it is possible that, in more complicated programs, the compiler might transform your program with various optimizations with the result that your program would fail when trying to modify a const object like this. For example, printf("%d", *y) could print “2” because the memory y points to has been changed to 2, while printf("%d", x) could print “1” because x is known (in the C model of computation) to be a constant 1.
consttells the compiler you intend not to change it. However, if you "cheat" and use a pointer you can change it, but I'll bet you saw a warning to that effect when you compiled. The warning you get withgccis, warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] y = &x; So theconstis ignored in that case.xin read-only memory in this instance (and making certain assumptions about how the C model of computation was implemented).constdon't mean constant but read only... yeah ok it's miss leading.warning: assigning to 'int *' from 'const int *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]when I compile your code... standard doesn't not describe this kind of specification, compiler are free to do what they like.