Casting away const

BCS none at anon.com
Sun Aug 8 15:55:59 PDT 2010


Hello simendsjo,

> I'm totally new to the const/immutable thing, so this might be a naive
> question..
> 
> The spec says:
> "modification after casting away const" => "undefined behavior"
> // ptr to const int
> const(int)* p;
> int* q = cast(int*)p;
> *q = 3;   // undefined behavior
> But why would you want to cast away const then? If it's for passing to
> a function that doesn't take const, you're just shooting yourself in
> the foot by giving it illegal data to work with.
> 
> This little test works:
> unittest
> {
> const int i = 10;
> const(int)* p = &i;
> assert(*p == 10);
> assert(p == &i);
> int* q = cast(int*)p;
> assert(q == &i);
> assert(*q == 10);
> *q = 1; // spec says undefined behavior

Your code at this point can do anything

> assert(*q == 1); // but the value is changed
> assert(*p == 1); // but p is also changed
> assert(p == q); // still same reference.
> assert(q == &i);
> assert(p == &i);
> assert(i == 10); // i still 10 though.. How is this possible?
> }

Because i is const int and initialized with a constant, the compiler is free 
to do things replace instances of i with the value rather than loading the 
value from ram. Allowing that sort of things is the reason for const and 
the undefined behavior bit is to prevent the compiler from needing to check 
for what you did.

Off hand, other ways that your example could fail include:
-the compiler putting i in a global variable (if this were in a recursive 
function...)
-combining it with other global consts, or even code, that happen to have 
the same bit pattern as 10 (at which point you just messed up code that uses 
them)
-putting it in a read only memory segment (and then "*q = 1" will seg-v)

-- 
... <IXOYE><





More information about the Digitalmars-d-learn mailing list