As others have said, you're exploiting undefined behavior. In your case, your program is able to execute without crashing because your compiler's linker allocated space for the "constant" MAX_VALUE
in RAM, and it was allocated in a RAM region whose attributes are not set as "read-only". I.e. it's being placed in writable RAM, even though you've declared it as const
.
On another system, MAX_VALUE
might be allocated in ROM (e.g. in an embedded system where the entire program is stored in memory-mapped flash space, and never copied to RAM). On such a system, you could try to write to MAX_VALUE
all you wanted and it would never change, unless you knew the magic incantation pattern to trigger the flash memory's erase/program operations, in which case, yes it would change, but not to the value you wanted to change it to. (And if you triggered an erase operation, a whole lot of bytes around it would quickly change to all 0xFF's!) But that's really only possible on primitive embedded systems where the ROM address space isn't write-protected by an MMU, MPU, or by its chip-select configuration.
On yet another system, MAX_VALUE
might be allocated in RAM, but in a section that's marked as read-only in the MMU/MPU. So even though the hardware would be physically capable of allowing its value to change at runtime, it is configured to trap/catch any attempt to do so, and will crash your program for an illegal access attempt (or other similar wording).
But as I said, on your system, since you can change the value of MAX_VALUE
at runtime (bypassing compiler safety by casting away its const
attribute), we know that on your system MAX_VALUE
is allocated in writable RAM.
But then you're of course asking, how could the line...
cout << "MAX_VALUE: " << MAX_VALUE << endl;
...print 90 when you had previously changed its value to 6? Well, the compiler is allowed to optimize that line by not even performing a read of MAX_VALUE
, using instead the initialization value from its definition, since in this compilation unit its initialization value is known. The const
qualifier is a promise to the compiler that you won't be changing it, and at the same time, a request to the compiler that it alert you if you ever mistakenly try to change it. But by casting away the const
attribute, you're bypassing that safety and the result is undefined behavior according to the C++ standard. In your case, your system will execute the code without crashing for the reasons I mentioned above.