Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > function pointers as function parameters

Reply
Thread Tools

function pointers as function parameters

 
 
Marlene Stebbins
Guest
Posts: n/a
 
      05-02-2005
I am experimenting with function pointers. Unfortunately, my C book has
nothing on function pointers as function parameters. I want to pass a
pointer to ff() to f() with the result that f() prints the return value
of ff(). The code below seems to work, but I would appreciate your
comments. Have I got it right? Does the function name "decay" to a pointer?


#include <stdio.h>
/* declares a function which takes an argument
that is a pointer to a function returning an int */
void f(int (*fptr)());
/* function returning an int */
int ff(void);

int main(void)
{
f(ff); /* pass the address of ff to f */

return 0;
}

void f(int (*fptr)())
{
int a;
a = (*fptr)(); /* deref the func pointer */
printf("%d\n", a);
return;
}

int ff(void)
{
return 2345;
}
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      05-02-2005


Marlene Stebbins wrote:
> I am experimenting with function pointers. Unfortunately, my C book has
> nothing on function pointers as function parameters. I want to pass a
> pointer to ff() to f() with the result that f() prints the return value
> of ff(). The code below seems to work, but I would appreciate your
> comments. Have I got it right? Does the function name "decay" to a pointer?


It might be simpler to say that the function name "is"
a pointer to the function, since there is no context in
which it does anything other than "decay."

Your code is correct (as far as I can see), but there
are a few opportunities for stylistic improvement:

> #include <stdio.h>
> /* declares a function which takes an argument
> that is a pointer to a function returning an int */
> void f(int (*fptr)());


You know more about the pointed-to function than the
type of its returned value: specifically, you know that
it takes no arguments. (How do you know this? Because
you supply no arguments when you call it.) On the general
principle that it's best to tell the compiler everything
you know, write the declaration as

void f(int (*fptr)(void));

This way, the compiler will protest if you inadvertently
try to call the pointed-to function with arguments. If
you do in fact want to pass arguments, say so:

void f2(int (*fptr)(double, int, const char*));

> /* function returning an int */
> int ff(void);
>
> int main(void)
> {
> f(ff); /* pass the address of ff to f */


Here's where ff "decays."

> return 0;
> }
>
> void f(int (*fptr)())


If you've provided a prototype as suggested above,
you should also do so here.

> {
> int a;
> a = (*fptr)(); /* deref the func pointer */


This can also be written `a = fptr();' without the
parentheses and the asterisk. Some people prefer to write
the call as you've done it, saying that it draws attention
to the fact that a function pointer variable (rather than
a function identifier) is being used. I personally don't
buy that argument, noting that

(*printf)("Hello, world!\n");

is equally legitimate and (IMHO) equally silly. However,
de gustibus non disputandum est (Latin for "There's just
no arguing with Gus").

> printf("%d\n", a);
> return;
> }
>
> int ff(void)
> {
> return 2345;
> }


--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
pete
Guest
Posts: n/a
 
      05-02-2005
Eric Sosman wrote:
>
> Marlene Stebbins wrote:
> > I am experimenting with function pointers.
> > Unfortunately, my C book has
> > nothing on function pointers as function parameters.
> > I want to pass a
> > pointer to ff() to f() with the result that f()
> > prints the return value
> > of ff(). The code below seems to work, but I would appreciate your
> > comments. Have I got it right?
> > Does the function name "decay" to a pointer?

>
> It might be simpler to say that the function name "is"
> a pointer to the function, since there is no context in
> which it does anything other than "decay."


The function name remains an expression of a function type
when it is an operand of the address operator.
You can force a non macro invocation of a standard library
function by calling it like
(&putchar)('\n');
which wouldn't make sense if putchar were a pointer.
If a function name were a pointer expression,
then it would be a valid operand of the sizeof operator.
For those two reasons,
I would not say that a function name is a pointer.

--
pete
 
Reply With Quote
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      05-02-2005
Marlene Stebbins wrote on 02/05/05 :
> #include <stdio.h>
> /* declares a function which takes an argument
> that is a pointer to a function returning an int */
> void f(int (*fptr)());
> /* function returning an int */
> int ff(void);
>
> int main(void)
> {
> f(ff); /* pass the address of ff to f */
>
> return 0;
> }
>
> void f(int (*fptr)())
> {
> int a;
> a = (*fptr)(); /* deref the func pointer */
> printf("%d\n", a);
> return;
> }
>
> int ff(void)
> {
> return 2345;
> }


You've got it (jist add 'void' into the () and it's all fine). Now, try
the Simple Way:

#include <stdio.h>

typedef int F (void);

static int ff (void)
{
return 2345;
}

static void f (F * pf)
{
/* deref the func pointer */
int a = pf ();

printf ("%d\n", a);
return;
}

int main (void)
{
/* pass the address of ff to f */
f (ff);

return 0;
}

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-02-2005
Eric Sosman <(E-Mail Removed)> writes:
> Marlene Stebbins wrote:
>> I am experimenting with function pointers. Unfortunately, my C book has
>> nothing on function pointers as function parameters. I want to pass a
>> pointer to ff() to f() with the result that f() prints the return value
>> of ff(). The code below seems to work, but I would appreciate your
>> comments. Have I got it right? Does the function name "decay" to a pointer?

>
> It might be simpler to say that the function name "is"
> a pointer to the function, since there is no context in
> which it does anything other than "decay."


Almost. A function name decays (is implicitly converted) to a pointer
in most contexts. The exceptions are when it's the operand of a unary "&"
(&ff yields a pointer-to-function, not a pointer-to-pointer-to-function),
and when it's the operand of sizeof (sizeof ff is illegal; if it
decayed in that context it would yield the size of a function
pointer).

[snip]
> This can also be written `a = fptr();' without the
> parentheses and the asterisk. Some people prefer to write
> the call as you've done it, saying that it draws attention
> to the fact that a function pointer variable (rather than
> a function identifier) is being used. I personally don't
> buy that argument, noting that
>
> (*printf)("Hello, world!\n");
>
> is equally legitimate and (IMHO) equally silly. However,
> de gustibus non disputandum est (Latin for "There's just
> no arguing with Gus").


Note that
(*printf)("Hello, world!\n");
isn't exactly equivalent to
printf("Hello, world!\n");
since the latter could invoke a macro. That's a special rule for
functions declared in standard headers. But if you want to avoid the
macro and call the actual function, you can just use parentheses:

(printf)("Hello, world!\n");

Hmm. Actually, since printf() takes a variable number of arguments,
implementing it as a macro is not possible in C90; I'm not sure
whether it's possible in C99. But I digress.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      05-03-2005
On Mon, 02 May 2005 18:59:12 +0000, pete wrote:

> Eric Sosman wrote:
>>
>> Marlene Stebbins wrote:
>> > I am experimenting with function pointers.
>> > Unfortunately, my C book has
>> > nothing on function pointers as function parameters.
>> > I want to pass a
>> > pointer to ff() to f() with the result that f()
>> > prints the return value
>> > of ff(). The code below seems to work, but I would appreciate your
>> > comments. Have I got it right?
>> > Does the function name "decay" to a pointer?

>>
>> It might be simpler to say that the function name "is"
>> a pointer to the function, since there is no context in
>> which it does anything other than "decay."

>
> The function name remains an expression of a function type
> when it is an operand of the address operator.
> You can force a non macro invocation of a standard library
> function by calling it like
> (&putchar)('\n');


That's true although in practice it tends to be written as

(putchar)('\n');

> which wouldn't make sense if putchar were a pointer.


But, yes, your form makes this point.

> If a function name were a pointer expression,
> then it would be a valid operand of the sizeof operator.
> For those two reasons,
> I would not say that a function name is a pointer.


It is a very similar argument to that for array names. Array names have
array type but in many cases an array "value" is given as a pointer to the
array's first element, so in those cases it appears to be a pointer. But
it isn't and as with functions &array and sizeof array show its true
nature.

Lawrence
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      05-03-2005
Lawrence Kirby wrote:
>
> On Mon, 02 May 2005 18:59:12 +0000, pete wrote:
>
> > Eric Sosman wrote:


> >> It might be simpler to say that the function name "is"
> >> a pointer to the function, since there is no context in
> >> which it does anything other than "decay."

> >
> > The function name remains an expression of a function type
> > when it is an operand of the address operator.
> > You can force a non macro invocation of a standard library
> > function by calling it like
> > (&putchar)('\n');

>
> That's true although in practice it tends to be written as
>
> (putchar)('\n');
>
> > which wouldn't make sense if putchar were a pointer.

>
> But, yes, your form makes this point.
>
> > If a function name were a pointer expression,
> > then it would be a valid operand of the sizeof operator.
> > For those two reasons,
> > I would not say that a function name is a pointer.

>
> It is a very similar argument to that for array names.
> Array names have array type but in many cases an array "value"
> is given as a pointer to the array's first element,
> so in those cases it appears to be a pointer.
> But it isn't and as with functions &array
> and sizeof array show its true nature.


I would agree with Eric Sosman's statement to the extent
that the only use of a value of an expression of a function type,
is that a pointer can be derived from it.

What constitutes the value of an array type, is more complicated.
The value of an array type (even an incomplete array type)
can be converted to a pointer.
The value of an array type can initialize an array.
char array[] = "";
The value of an array type structure member,
is a byte by byte copy when the structure
is an operand of the assignment operator.

--
pete
 
Reply With Quote
 
Jonathan Bartlett
Guest
Posts: n/a
 
      05-03-2005
Your code is good. Let me also point you to an article I wrote recently
involving the subject:

http://www-128.ibm.com/developerwork...-highfunc.html

Some of the code in there is non-standard C, but works for most
platforms most people deal with.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017
 
Reply With Quote
 
Michael Wojcik
Guest
Posts: n/a
 
      05-03-2005

In article <(E-Mail Removed)>, Keith Thompson <(E-Mail Removed)> writes:
> Eric Sosman <(E-Mail Removed)> writes:
> >
> > It might be simpler to say that the function name "is"
> > a pointer to the function, since there is no context in
> > which it does anything other than "decay."

>
> Almost. A function name decays (is implicitly converted) to a pointer
> in most contexts. The exceptions are when it's the operand of a unary "&"
> (&ff yields a pointer-to-function, not a pointer-to-pointer-to-function),
> and when it's the operand of sizeof (sizeof ff is illegal; if it
> decayed in that context it would yield the size of a function
> pointer).


I was mulling over the hypothesis that the & and * operators, when
applied to function names, simply did nothing, but your last example
made me think of a possible counterexample. Is the following a
strictly conforming expression?

sizeof &main;

Or, if you prefer the full-program version:

#include <stdio.h>
int main(void) {
printf("%lu\n", (unsigned long) sizeof &main);
return 0;
}

If it is, aside from that, are there any other cases where the & and
* operators have any effect when applied to a function name?

--
Michael Wojcik (E-Mail Removed)

"We are facing a dire shortage of clowns," said Erickson, also known as
Jingles.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      05-03-2005


pete wrote:
> Lawrence Kirby wrote:
>
>>On Mon, 02 May 2005 18:59:12 +0000, pete wrote:
>>
>>
>>>Eric Sosman wrote:

>
>
>>>> It might be simpler to say that the function name "is"
>>>>a pointer to the function, since there is no context in
>>>>which it does anything other than "decay."
>>>
>>>The function name remains an expression of a function type
>>>when it is an operand of the address operator.
>>>You can force a non macro invocation of a standard library
>>>function by calling it like
>>> (&putchar)('\n');

>>
>>That's true although in practice it tends to be written as
>>
>> (putchar)('\n');
>>
>>
>>>which wouldn't make sense if putchar were a pointer.

>>
>>But, yes, your form makes this point.
>>
>>
>>>If a function name were a pointer expression,
>>>then it would be a valid operand of the sizeof operator.
>>>For those two reasons,
>>>I would not say that a function name is a pointer.

>>
>>It is a very similar argument to that for array names.
>>Array names have array type but in many cases an array "value"
>>is given as a pointer to the array's first element,
>>so in those cases it appears to be a pointer.
>>But it isn't and as with functions &array
>>and sizeof array show its true nature.

>
>
> I would agree with Eric Sosman's statement to the extent
> that the only use of a value of an expression of a function type,
> is that a pointer can be derived from it.


Although it's flattering to learn that someone agrees with
me, it is also a bit embarrassing -- because I have come to
*dis*agree with myself

I said there was no context in which a function identifier
doesn't "decay" to a pointer to the function, but Keith
Thompson has convinced me I was wrong. Specifically:

- In the context `&func', the `func' part does not behave
like a pointer-to-function. If it did, the entire
expression would be pointer-to-pointer-to-function --
but, strangely enough, both `func' and `&func' (and
even `&&&&&&&func') are pointer-to-function.

- In the context `sizeof func', the `func' part does not
behave like a pointer-to-function. If it did, the
expression would evaluate to the size of a function
pointer, but in actuality the expression produces a
diagnostic.

The second point is debatable: since the context is not
valid C at all, its odd behavior doesn't matter. One might
equally well make arguments about the array-indexing operator
in the context `[4]"Hello"'; interesting things might be said,
but they'd have little to do with C. But even if one rejects
the second point, the first seems unassailable: Keith is right
and I was wrong, R-O-N-G, wrong.

--
(E-Mail Removed)

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Passing member function pointers are template parameters Dilip C++ 3 11-06-2006 11:42 PM
Smart pointers and member function pointers n2xssvv g02gfr12930 C++ 3 11-27-2005 10:51 AM
void pointers & void function pointers Peter Goddard C Programming 3 05-16-2005 09:44 PM
Template specialization of pointers with function pointers Phil C++ 1 09-16-2003 02:17 AM



Advertisments