A "how does it work" type question

M

mdh

May I ask this.
Given the declaration:
int myf( int, int);

and a function pointer:

(*fp)=int myf(int, int);

where I am initializing fp to point at myf....or trying to..


int main (){

i=myf (3, 4);

return 0;

}

A definition of:

int myf( int a, int b){
return a+b;
}

What goes on in the workings of C when myf is called, and how does
this differ from calling myf like this?
(*fp)(3,4);

If I am not that clear with this question, then it is because I am not
that clear about what I am asking, but I am trying to get a conceptual
picture of what happens when functions are called....and marrying this
idea with function pointers. I may be making it a lot more complicated
than it really is....which is more than likely.
Well, here goes...and wearing the usual head protective gear for all
the answers :)
 
E

Eric Sosman

mdh said:
May I ask this.
Given the declaration:
int myf( int, int);

Okay.
and a function pointer:

(*fp)=int myf(int, int);

Gibberish. I *think* what you're talking about is

int (*fp)(int, int) = myf;

.... but that's only a guess.
where I am initializing fp to point at myf....or trying to..


int main (){

i=myf (3, 4);

return 0;

}

A definition of:

int myf( int a, int b){
return a+b;
}

What goes on in the workings of C when myf is called, and how does
this differ from calling myf like this?
(*fp)(3,4);

If I am not that clear with this question, then it is because I am not
that clear about what I am asking, but I am trying to get a conceptual
picture of what happens when functions are called....and marrying this
idea with function pointers. I may be making it a lot more complicated
than it really is....which is more than likely.
Well, here goes...and wearing the usual head protective gear for all
the answers :)

Do you see the difference between

int x;
x = 42;

and

int x, y;
int *p = &x;
if (full_moon)
p = &y;
*p = 42;

? In the first case, the identity of `x' is known at compile
time and unchangeable at run time: The assignment always stores
a value in `x' and in no other variable. In the second case,
the assignment stores to a variable whose identity is not known
at compile time but is instead determined at run time. In some
executions of the code 42 is stored in `x' and in others it is
stored in `y'. Is that clear?

The difference between using an explicit function name and
a function pointer is the same: In one case the function being
called is known at compile time and unchangeable thereafter; in
the other, the function's type is known (just as it is known that
`*p' is an int and not a double) but its identity is determined
at run time. Let's flesh out your example in parallel with mine:

int myf(int, int);
int x = myf(3, 4);

as opposed to

int myf(int, int);
int yourf(int, int);
int x;
int (*fp)(int, int) = myf;
if (full_moon)
fp = yourf;
x = (*fp)(3, 4); /* alternatively, x = fp(3, 4); */

The function called in the final line could be either myf or
yourf, depending on the phase of the moon.
 
S

Stephen Sprunk

mdh said:
May I ask this.
Given the declaration:
int myf( int, int);

and a function pointer:

(*fp)=int myf(int, int);

where I am initializing fp to point at myf....or trying to..

Provided fp is declared correctly, you would use:

fp = myf; /* note the lack of ()s */
int main (){
i=myf (3, 4);
return 0;
}

A definition of:

int myf( int a, int b){
return a+b;
}

What goes on in the workings of C when myf is called, and
how does this differ from calling myf like this?
(*fp)(3,4);

That would normally be written:

fp(3,4); /* the same as myf(3,4); */
If I am not that clear with this question, then it is because I am
not that clear about what I am asking, but I am trying to get a
conceptual picture of what happens when functions are
called....and marrying this idea with function pointers. I may be
making it a lot more complicated than it really is....which is
more than likely.

While not exactly correct, you can think of myf -- without the ()s -- as a
function pointer that is initialized to point to the definition you gave.
Once you assign another function pointer, fp, to point to the same function,
you can call either of them the same way. A typical implementation will
treat the two calls differently under the hood, but they look the same in C.

S
 
K

Keith Thompson

mdh said:
May I ask this.
Given the declaration:
int myf( int, int);

and a function pointer:

(*fp)=int myf(int, int);

That's not valid C, but see below.
where I am initializing fp to point at myf....or trying to..


int main (){

i=myf (3, 4);

return 0;

}

A definition of:

int myf( int a, int b){
return a+b;
}

What goes on in the workings of C when myf is called, and how does
this differ from calling myf like this?
(*fp)(3,4);
[...]

Take a look at this program, particularly the comments:

#include <stdio.h>

/* Declare myf (not really necessary here). */
int myf(int, int);

/* Define myf. */
int myf(int a, int b)
{
return a + b;
}

int main(void)
{
/* Declare fp as a pointer-to-function, of a type appropriate
* so it can point to myf.
*/
int (*fp)(int, int);

int i, j;

/* Assign a value to fp so it points to myf. */
fp = myf;

/* Call the function indirectly via the pointer. */
i = fp(2, 3);

/* Call the function directly. */
j = myf(4, 5);

/* Display the results. */
printf("i = %d, j = %d\n", i, j);

return 0;
}

A function pointer points to a function. Typically it simply contains
the memory address of the function's entry point, but that's not
specified by the language; it could contain descriptor information, or
just an index into a system table.

Calling a function via a pointer does the same thing as calling it
directly. The difference (and the reason function pointers are
useful) is that you can, by assigning different values to the function
pointer, determine at run time which function is invoked by a
different call. See the standard qsort() function for an example of
this; there's no way qsort() could call your comparison function
directly, but it can call it indirectly because you've passed a
pointer to it as an argument.

You can probably ignore the following, at least for now; I'm going to
go into some of the more abstruse aspects of the language.

An indirect function call (using a function pointer) and a direct
function call (using the function's name) are really the same thing.
Any reference to a function's name (other than as the operand of a
unary "&" or "sizeof" operator) is implicitly converted to a pointer
to the function. This conversion happens even when the name is part
of a function call. So why does the function call work? Because the
function call operator requires a function *pointer* as its first
operand. Even a direct function call uses a function pointer, one
derived from the function name. (This is very similar to the way the
array indexing operator actually requires a pointer to the array's
first element, not an array value.)
 
J

Joe Wright

mdh said:
May I ask this.
Given the declaration:
int myf( int, int);

and a function pointer:

(*fp)=int myf(int, int);

where I am initializing fp to point at myf....or trying to..


int main (){

i=myf (3, 4);

return 0;

}

A definition of:

int myf( int a, int b){
return a+b;
}

What goes on in the workings of C when myf is called, and how does
this differ from calling myf like this?
(*fp)(3,4);

If I am not that clear with this question, then it is because I am not
that clear about what I am asking, but I am trying to get a conceptual
picture of what happens when functions are called....and marrying this
idea with function pointers. I may be making it a lot more complicated
than it really is....which is more than likely.
Well, here goes...and wearing the usual head protective gear for all
the answers :)

This is how I usually do it.

#include <stdio.h>

/* Define the function */
int myf(int a, int b) {
return a + b;
}

/* Define a pointer to function */
int (*fp)(int, int);

int main(void) {
fp = myf; /* Point fp to myf() */
printf("%d\n", fp(3, 4));
return 0;
}
 
M

mdh

Take a look at this program, particularly the comments:


/* Declare fp as a pointer-to-function, of a type appropriate
* so it can point to myf.
*/
int (*fp)(int, int);

/* Assign a value to fp so it points to myf. */
fp = myf;

/* Call the function indirectly via the pointer. */
i = fp(2, 3);

/* Call the function directly. */
j = myf(4, 5);


A function pointer points to a function.
Calling a function via a pointer does the same thing as calling it
directly.
You can probably ignore the following, at least for now; I'm going to
go into some of the more abstruse aspects of the language.

Nope...this is the part I was particularly interested in.
An indirect function call (using a function pointer) and a direct
function call (using the function's name) are really the same thing.
Any reference to a function's name (other than as the operand of a
unary "&" or "sizeof" operator) is implicitly converted to a pointer
to the function. This conversion happens even when the name is part
of a function call. So why does the function call work? Because the
function call operator requires a function *pointer* as its first
operand. Even a direct function call uses a function pointer, one
derived from the function name.


Thanks...this is what I suspected...( well not exactly in those terms)
but that does make the syntax of the function pointer make more sense.
Thanks Keith.
 
M

mdh

Is that clear?


Yes...I get that. I guess my question (and example) did not convey the
full meaning of what I was trying to ask. KT inadvertantly answered my
question below.



The difference between using an explicit function name and
a function pointer is the same: In one case the function being
called is known at compile time and unchangeable thereafter; in
the other, the function's type is known (just as it is known that
`*p' is an int and not a double) but its identity is determined
at run time.


Yes...that certainly re-inforces my understanding from a different
angle.
So, conceptually, is this a fair way of looking at it? ( which may
not exactly speak to the issue you are telling me).

Whether the fuction is explicityly named or called by a pointer, the
functions arguments and return type are known to the compiler by the
declaration. So, if an argument is expected, the next **bit/s of
information** will have to be ( ....arguments), (whether that is
preceded by the explicit function name or a function pointer.
And that is why:

int myf(arguments)

and

(*fp)(arguments)

are equivalent.(assuming fp points to myf)
 
M

mdh

This is how I usually do it.

#include <stdio.h>

/* Define the function */
int myf(int a, int b) {
return a + b;

}

/* Define a pointer to function */
int (*fp)(int, int);

int main(void) {
fp = myf; /* Point fp to myf() */
printf("%d\n", fp(3, 4));
return 0;
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---


I also like
"If you cannot explain a concept to a 4 year old, you do not
understand it yourself"

Thank you Joe.
 
M

mdh

While not exactly correct, you can think of myf -- without the ()s -- as a
function pointer that is initialized to point to the definition you gave.
Once you assign another function pointer, fp, to point to the same function,
you can call either of them the same way. A typical implementation will
treat the two calls differently under the hood, but they look the same in C.


Thanks Stephen...
Despite the fact that C is a "language" I really do find it helpful to
have some conceptual idea of what I am doing.
So thanks again
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top