Re: casting const away



On Thu, 06 Jan 2011 11:53:23 +0100, copx wrote:

"copx" wrote in message news:ig3l22$3hb$1@xxxxxxxxxxxxxxxxxxxx Here's
some compile-ready code which illustrates the issue:

#include <stdio.h>

void foo(const int *c)
{
*((int *)c) = 'B';
}


int main(void)
{
int a = 'A';

foo(&a);

putchar(a);

return 0;
}


====
Result: no warnings, prints 'B';

As I wrote in the other post I think I have figured it out already.

In this example, as you say, it appears to work, but I believe the key
term there is "appears to".

You've essentially lied to the compiler; telling it (where main calls
foo) that the value will not - indeed cannot - be modified, but then you
modify it.

AIUI, the compiler is free to believe what it's told - that the parameter
is, indeed, const and thus won't be modified. In a somewhat less trivial
example, it may well decide to stuff the value ('A') into a register,
then use that in passing the value to putchar, meaning that the
modifications you made in foo() have no effect on the value displayed -
even though the value of a itself may in fact have been modified.

Something like this (pseudo assembler):

load reg1, 'A'
load reg2, reg1 ; since the value won't be modified, cache it
store [a], reg1 ; assign to a
load reg1, @a ; get address of a into reg1
call foo,reg1 ; call foo with address of a, in reg1
load reg1, reg2 ; retrieve cached value
call putchar, reg1 ; use cached - original - value for putchar


The fact you are in essence lying to the compiler about what main can
expect to happen - or, rather, not happen - to a suggests to me the
compiler is free to do whatever it thinks is right - which may differ
from run to run, optimization to optimization, compiler to compiler, etc.

.