473,725 Members | 1,740 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

function pointers as function parameters

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;
}
Nov 14 '05 #1
27 2482


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)("Hell o, 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;
}


--
Er*********@sun .com

Nov 14 '05 #2
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
Nov 14 '05 #3
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++

Nov 14 '05 #4
Eric Sosman <er*********@su n.com> 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)("Hell o, 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)("Hell o, 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_Keit h) ks***@mib.org <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.
Nov 14 '05 #5
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
Nov 14 '05 #6
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
Nov 14 '05 #7

In article <ln************ @nuthaus.mib.or g>, Keith Thompson <ks***@mib.or g> writes:
Eric Sosman <er*********@su n.com> 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 mi************@ microfocus.com

"We are facing a dire shortage of clowns," said Erickson, also known as
Jingles.
Nov 14 '05 #8


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.

--
Er*********@sun .com

Nov 14 '05 #9
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
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2606
by: John Miles | last post by:
Hi -- This is a bit of an implementation-specific problem, but I'd like to post it here to see if there's a general answer within the auspices of the language. I'm developing a high(er)-level scripting language designed explicitly to complement C++. One of the language's features is the ability to pass "out" parameters to an MSVC __cdecl function by reference. After the C++ function returns, but before popping the parameters from the
11
2712
by: JKop | last post by:
Take the following simple function: unsigned long Plus5Percent(unsigned long input) { return ( input + input / 20 ); } Do yous ever consider the possibly more efficent:
26
3128
by: Adam Warner | last post by:
Hello all, I'm very new to C but I have a number of years of Common Lisp programming experience. I'm trying to figure out ways of translating higher order concepts such as closures into C. The code will not be idiomatic C. GCC has an extension to ISO C that permits nested functions: <http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html> For implementing closures they have a serious limitation:
13
332
by: munni | last post by:
hi i want to write a program on function pointers where i have not written any programs using function pointers till now. i want to take an array of 26 functions which r to be pointed by this pointer. pls give me an example to write a program. thanking u in advance munni
12
8388
by: srinivas.satish | last post by:
Hi, is it possible to typecast a function pointer to two different prototypes. eg., typedef void (functptr1 *) (int , int); typedef void (functptr2 *) (int); functptr1 fptr; fptr = somefunction_name; fptr(10,20); fptr = (functptr2)someotherfunction_name;
16
7601
by: arne | last post by:
Hi all, imagine I call a function, but omit one of the parameters, like: foo.c: void foo( int a, int b ) { /* do something with a and b */ return; }
12
7862
by: claudiu | last post by:
Hi, I'll go straight to the first question. Why does the code below compile? void f(int i = 0); int main() { (&f)();
12
4647
by: Googy | last post by:
Hi!! Can any one explain me the meaning of following notations clearly : 1. typedef char(*(*frpapfrc()))(); frpapfrc f; 2. typedef int (*(arr2d_ptr)()); arr2d_ptr p; 3. typedef int (*(*(*ptr2d_fptr)()))();
2
4202
by: Rahul | last post by:
Hi, I planning to replace the switch-case with an array of function pointers, the index for the array would be the case integers. Each case block would be implemented as a seperate function. It works fine when all the functions have the exact signature like the return types and formal input parameters. In my case, some functions accept a different number of arguements. Hence i can't have the array of different function pointers, is...
20
2230
by: MikeC | last post by:
Folks, I've been playing with C programs for 25 years (not professionally - self-taught), and although I've used function pointers before, I've never got my head around them enough to be able to think my way through what I want to do now. I don't know why - I'm fine with most other aspects of the language, but my brain goes numb when I'm reading about function pointers! I would like to have an array of structures, something like
0
9392
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9246
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9162
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8069
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4505
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4773
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3211
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2619
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2150
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.