If an object is declared const
, an implementation is allowed to store it in such a way that attempts to modify it could cause hardware traps, without having any obligation to ensure any particular behavior for those traps. If one constructs a const
pointer to such an object, recipients of that pointer will not generally be allowed to write it, and would thus be in no danger of triggering those hardware traps. If code casts away the const
-ness and writes to the pointer, a compiler would be under no obligation to protect the programmer against any hardware oddities that might occur.
Further, in the event that a compiler can tell that a const
object is always going to contain a particular sequence of bytes, it could inform the linker of that, and allow the linker to see if that sequence of bytes occurs anywhere in the code and, if so, regard the address of the const
object as being the location of that sequence of bytes (complying with various restrictions about different objects having unique addresses might be a little tricky, but it would be permissible). If the compiler told the linker that a const char[4]
was always supposed to contain a sequence of bytes that happened to appear within the compiled code for some function, a linker could assign to that variable the address within the code where that byte sequence appears. If the const
was never written, such behavior would save four bytes, but writing to the const
would arbitrarily change the meaning of the other code.
If writing to an object after casting away const
was always UB, the ability to cast away const-ness wouldn't be very useful. As it is, the ability often plays a role in situations where a piece of code holds onto pointers--some of which are const
and some of which will need to be written--for the benefit of other code. If casting away the const-ness of const
pointers to non-const
objects weren't defined behavior, the code which is holding the pointers would need to know which pointers are const
and which ones will need to be written. Because const-casting is allowed, however, it is sufficient for the code holding the pointers to declare them all as const
, and for code which knows that a pointer identifies a non-const object and wants to write it, to cast it to a non-cast pointer.
It might be helpful if C++ had forms of const
(and volatile
) qualifiers which could be used on pointers to instruct the compiler that it may (or, in the case of volatile
, should) regard the pointer as identifying a const
and/or volatile
object even if the compiler knows that the object is, and knows that it isn't const
and/or isn't declared volatile
. The former would allow a compiler to assume that the object identified by a pointer wouldn't change during a pointer's lifetime, and cache data based upon that; the latter would allow for cases where a variable may need to support volatile
accesses in some rare situations (typically at program startup) but where the compiler should be able to cache its value after that. I know of no proposals to add such features, though.
const
is a promise from the programmer to the compiler (and a contract that other programmers reusing the component agree on), no more and no less. The compiler may or may not do something differently according to that promise, but that is circumstantial. Now, the thing is, if something is not constant, you should not give that promise in the first place. – Disdain