« Previous | Next»

Linus about "const pointers"

Posted by coldtobi | 28 Jan, 2008, 21:00

The concept of the C-modifier "const" is often misunderstood. On a recent question one person asked why there was a "const" parameter to the kfree syscall.

As this issues comes up there-and-then, I am glad, that Linus clearified: (Sorry for the long quote -- but he is just right)

					"const" has *never* been about the thing not being modified. Forget all 
	that claptrap. C does not have such a notion.
	"const" is a pointer type issue, and is meant to make certain mis-uses 
	more visible at compile time. It has *no* other meaning, and anybody who 
	thinks it has is just setting himself up for problems.
	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
	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:
	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:
	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.
	So never believe that "const" is some guarantee that the memory under the 
	pointer doesn't change.  That is *never* true. It has never been true in 
	C, since there can be arbitrary pointer aliases to that memory that aren't 
	actually const. If you think "const *p" means that the memory behind "p" 
	is immutable, you're simply wrong.
	Anybody who thinks that kfree() cannot (or should not) be const doesn't 
	understand the C type system.
	Linus
	
					[From: http://kerneltrap.org/Linux/C_Semantics_Constants_and_Pointers ] 
	

  



<—&mdash Showing ERROR? Click here!


Linux / Debian | Comments (0) | Trackbacks (0)

Related Articles:

0 Comments | "Linus about "const pointers"" »

Add comment

 

 This is the ReCaptcha Plugin for Lifetype

Due to German legislation, all comments are moderated. If you get NO error message, your comment is accepted by the system and will be released at the earliest opportunity. Sorry for the inconvenience this might cause.

Inappropiate comments might be edited or not accepted.