DragonFly kernel List (threaded) for 2004-11
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: learning dragonfly or C...
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
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]