Possible Duplicate:
Sell me on const correctness
What is the usefulness of keyword const
in C
or C++
since it's allowed such a thing?
void const_is_a_lie(const int* n) { *((int*) n) = 0; } int main() { int n = 1; const_is_a_lie(&n); printf("%d", n); return 0; }
Output: 0
It is clear that const
cannot guarante the non-modifiability of the argument.
const
is a promise you make to the compiler, not something it guarantees you.
For example,
void const_is_a_lie(const int* n) { *((int*) n) = 0; } #include <stdio.h> int main() { const int n = 1; const_is_a_lie(&n); printf("%d", n); return 0; }
Output shown at http://ideone.com/Ejogb is
1
Because of the const
, the compiler is allowed to assume that the value won't change, and therefore it can skip rereading it, if that would make the program faster.
In this case, since const_is_a_lie()
violates its contract, weird things happen. Don't violate the contract. And be glad that the compiler gives you help keeping the contract. Casts are evil.
In this case, n
is a pointer to a constant int
. When you cast it to int*
you remove the const
qualifier, and so the operation is allowed.
If you tell the compiler to remove the const
qualifier, it will happily do so. The compiler will help ensure that your code is correct, if you let it do its job. By casting the const-ness away, you are telling the compiler that you know that the target of n
is non-constant and you really do want to change it.
If the thing that your pointer points to was in fact declared const
in the first place, then you are invoking undefined behavior by attempting to change it, and anything could happen. It might work. The write operation might not be visible. The program could crash. Your monitor could punch you. (Ok, probably not that last one.)
void const_is_a_lie(const char * c) { *((char *)c) = '5'; } int main() { const char * text = "12345"; const_is_a_lie(text); printf("%s\n", text); return 0; }
Depending on your specific environment, there may be a segfault (aka access violation) in const_is_a_lie
since the compiler/runtime may store string literal values in memory pages that are not writable.
The Standard has this to say about modifying const objects.
7.1.6.1/4 The cv-qualifiers [dcl.type.cv]
Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior
"Doctor, it hurts when I do this!" "So don't do that."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With