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