In the particular case of kfree(), the pointer argument *should* be const,
and the fact that the C library gets this wrong is not the kernels
problem, it's a problem with the C library.
Why?
- From a very obvious and very *real* caller perspective, "free()" really
doesn't change the thing the pointer points to. It does something
totally different: it makes the *pointer* itself invalid.
In other words, if you think that "kfree()" changed the thing you
free'd, you're simply wrong. It did no such thing. The memory is 100%
the same, it's just that you cannot access it any more, and if you try,
you'll get somebody elses memory.
In other words, "kfree()" can be const.
- Anything that *can* take a const pointer should always do so.
Why? Because we want the types to be as tight as possible, and normal
code should need as few casts as possible.
Here's a question for you: let's say that you have a structure that
has a member that is never changed. To make that obvious, and to allow
the compiler to warn about mis-use of a pointer, the structure should
look something like
Code:
struct mystruct {
const char *name;
..
and let's look at what happens if the allocation of that const thing is
dynamic.
The *correct* way to do that is:
Code:
char *name = kmalloc(...)
/* Fill it in */
snprintf(name, ...)
mystruct->name = name;
and there are no casts anywhere, and you get exactly the semantics you
want: "name" itself isn't constant (it's obviously modified), but at
the same time the type system makes it very clear that trying to change
it through that mystruct member pointer is wrong.
How do you free it?
That's right, you do:
Code:
kfree(mystruct->name);
and this is why "kfree()" should take a const pointer. If it doesn't,
you have to add an *incorrect* and totally useless cast to code that
was correct.