Bug in wimp.h
Jonathan Coxhead
jonathan.coxhead at philips.com
Fri Aug 25 18:40:40 BST 2000
Chris Rutter wrote:
| Well, I'm aware that you can perform a const-removing cast and then
| write away, but don't you run the risk of invoking undefined behaviour?
Only if, once you follow back through all the pointers, the *actual
object* being written to was declared |const|. Otherwise, there can be a
long compilicated chain of casts between const and non-const pointer types,
and the result will still be one you expect.
Obviously, this can only be checked at run-time. This is a weakness in
the strength of the const qualifier in C. A different language could do it
differently.
| I must have misunderstood the purpose of `const': in simple terms, I
| thought it was, amongst other things, to allow a function to declare
| `I don't modify the the object this pointer points to', so that the
| caller doesn't have to flush any cached values held in local/register
| memory from that object.
`I don't modify the the object this pointer points to **through this
pointer**'
| If this guarantee doesn't hold in this way, then what /is/ the purpose
| of `const'?
The purpose is exactly that---it's just that, this being C, there's a
back door.
If you never cast away const, you have the safety you require. Any
halfway-sensible coding guidelines would contain that proviso.
| Follow this chain of reasoning:
|
| * String literals are nonwritable in ANSI C.
|
| * It is most /definitely/ legal to pass a string literal to a standard
| library function which declares that it takes a `const char *'.
|
| * Therefore (and this is the tenuous step), all functions which, for
| example, declare that they take a `const char *' guarantee that they
| /will not/ write to the memory the passed pointer refers to.
---via that pointer!
| * /Therefore/, a caller function is at liberty to assume that the
values
| contained in an object passed to a function as `const' will remain
| /unmodified/ after the call to the function.
Nope. It can only do that if it has seen the definition of the object,
and it is const.
| * Thus, if you cast away `const', you're risking breaking assumptions
made
| elsewhere in the code.
|
| Hence my original point: in this code:
|
| const char nm[12] = "*";
| wimp_load_template(..., nm, ...);
| printf("%c\n", nm[0]);
|
| you can legally get the output `*', /even if/ `nm[0]' has been modified
to
| contain another value by the innards of wimp_load_template().
True. |nm| is const, so the compiler can assume that nothing changes it--
it can allocate in ROM, and attempts to write to it can abort, for example.
(It can assume that even if wimp_load_template() takes a |char *| argument.)
/|
o o o (_|/
/|
(_/
More information about the oslib-user
mailing list