learning dragonfly or C...

Devon H. O'Dell dodell at sitetronics.com
Wed Nov 10 23:44:43 PST 2004


George Georgalis wrote:
[snip]
This is the part of the diff that interests me:

-	struct vnode **vpp, *vp;
+	struct vnode *vp;
 	Elf_Phdr *phdr;
 	struct file *fp;
 	int error;
 	TRACE_ENTER;
-	vpp = &vp;
I have a general idea about the use of pointers, but don't really
understand how they are used. What exactly does this syntax mean?
        struct vnode **vpp, *vp;
        vpp = &vp;
The other changes explain it a little to me: a degree of pointer
reference has been removed and the function is basicly a derivative
of the former. Is that what's happening?  Any other comments on what
that block of code does, or tries to do, are more than welcome.
// George
The declaration:

	struct vnode **vpp, *vp;

is declaring the following:

 o	a pointer to a pointer to memory containing type struct vnode
 o	a pointer to memory containing type struct vnode
The names most likely signify ``vnode pointer pointer'' and ``vnode 
pointer'', as you probably expected.

The statement:

	vpp = &vp

is ``dereferencing'' vp. Dereferencing effectively provides the address 
in memory of a variable.

The code Matt fixed seems redundant. Namely, there was no need for the 
creation of the extra variable, nor the initialization. The only place 
the double pointer is expected is in ckpt_fhtovp(), where vpp is 
obviously equivalent to &vp (the assignment is never modified). It 
doesn't contribute to readability (in fact, it makes it somewhat less 
readable, in my opinion) and, because the vpp is only used once, it's 
only taking time and space for the creation and assignment. Don't ask me 
how much, probably nanoseconds.

When do you usually need to dereference variables? Why is it useful? 
Dereferencing variables is useful when you want to modify their values 
inside another function, which you can't do if you don't have the 
variable's address. Take, for example, the following code (it's not 
optimal, it's just for illustrating the point):

#include <stdio.h>

void
modfunction(int bar)
{
	bar = 3; /* Change bar to 3 */
	printf("%d\n", bar);
	return;
}
int
main (void)
{
	int foo = 2;
	printf("foo is: %d\n", foo);
	printf("modfunction makes: ");
	modfunction(foo);
	printf("foo is now: %d\n", foo);
}
When you run this program, you see:

$ ./test
foo is: 2
modfunction makes: 3
foo is now: 2
This is because when C sends a variable to a function, it sends that 
data by value. Thus, instead of sending the actual variable foo to 
modfunction for modification, it's sending the value of variable foo.

To get the desired behavior, the code becomes:

#include <stdio.h>

void
modfunction(int *bar)
{
	*bar = 3; /* Change bar to 3 */
	printf("%d\n", *bar);
	return;
}
int
main (void)
{
	int foo = 2;
	printf("foo is: %d\n", foo);
	printf("modfunction makes: ");
	modfunction(&foo);
	printf("foo is now: %d\n", foo);
}
And now we have:

$ ./test
foo is: 2
modfunction makes: 3
foo is now: 3
This time, we ``dereferenced'' our variable foo (and, on a sidenote, I 
don't know why it's called dereferencing, I think it's a horrible name 
and substitute it mentally with ``grab the address of'' whenever I see 
it). We changed modfunction to expect a pointer to a location in memory 
of type int. Then we change the value pointed to by bar (when not in an 
assignment, ``*bar'' is read as the value of the location pointed to by 
bar; ``bar'' is the location) to 3 (*bar = 3).

Since the actual contents in memory have been modified, when we return 
out of modfunction, the value of foo has been changed. Remember, we 
effectively changed the memory that contained foo.

How is this useful? In the above example, it really isn't. You can just 
keep in mind that when you see variables passed by reference, that they 
are probably going to be modified. It's useful for modifying arrays of 
strings, multidimensional arrays, structures, and pretty much anything 
else that you might come across.

Hope this was of help.

Kind regards,

Devon H. O'Dell





More information about the Kernel mailing list