Bug in wimp.h
Chris Rutter
chris at willow.armlinux.org
Wed Aug 23 19:57:16 BST 2000
On Mon, 21 Aug 2000, Jonathan Coxhead wrote:
> | The compiler's perfectly at liberty to feed you back nm[0] == '*' and
> | nm[1] == '\0' after that call, when clearly those memory locations will
> have
> | been updated.
>
> Actually, it can't. The inside of wimp_load_template() (if written in C)
> would be completely within its rights to contain code like this:
>
> wimp_load_template (..., char const *name, ...)
> {
> char *name_var = (char *) name; /*cast away const*/
> name [0] = ...;
> }
>
> and indeed, that's pretty much what it does.
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?
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.
If this guarantee doesn't hold in this way, then what /is/ the purpose
of `const'?
It's tempting to answer with a tautology (`because you might receive a
`const' argument and won't be able to use it with the function'), but
please don't. :-)
> But there *is* a problem, and here it is:
>
> char const nm [12] = "*";
> wimp_load_template (..., nm, ...);
>
> Here, |nm| is actually const. It could be allocated in read-only memory,
> for example. So casting away const inside is illegal. (In the first
> example, |nm| was a variable.) Of course, the inside of the function has no
> way of knowing whether its argument is "really" const or not, which is why
> casting away const is a bad thing to do. Nevertheless, it is legal code.
Yes, precisely! This is the point I was trying to make. 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.
* /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.
* 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().
I suspect I may have misunderstood the `const guarantee': could you explain
where my reasoning falls down?
> Even it broke code, we would still fix it, because the current situation
> is a bug, and we don't care about bug-compatibility; only feature-
> compatibility.
Very noble point of view.
Is there any analysis of the average space taken by OSLib veeners in
OSLib-using RISC OS applications? (I'm wondering whether it would be
worth DLLization.)
^[1]
c.
[1] An Americanism. ;-)
More information about the oslib-user
mailing list