Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > *generic* pointer to function(s)?

Reply
Thread Tools

*generic* pointer to function(s)?

 
 
juerg.lemke@yahoo.com
Guest
Posts: n/a
 
      12-03-2007
Hi everyone

I am interested in having multiple functions with different prototypes
and deciding, by setting a pointer, which of them to use later in the
program.

Eg:

int f1(void);
char* f2(int);
/* ... many more of these to choose from */

/* ? correct declaration of generic_ptr ? */

if (/*...*/)
generic_ptr = f1;
else
generic_ptr = f2;

generic_ptr(/* using correct args */)

How should I define generic_ptr? Is (void*) ok? It seems to work on my
machine, but I would like to know if this is standard/portable.

Thank you for any help

Juergen
 
Reply With Quote
 
 
 
 
Peter Nilsson
Guest
Posts: n/a
 
      12-03-2007
(E-Mail Removed) wrote:
> Hi everyone
>
> I am interested in having multiple functions with different
> prototypes and deciding, by setting a pointer, which of
> them to use later in the program.
>
> Eg:
>
> int f1(void);
> char* f2(int);
> /* ... many more of these to choose from */
>
> /* ? correct declaration of generic_ptr ? */
>
> if (/*...*/)
> generic_ptr = f1;
> else
> generic_ptr = f2;
>
> generic_ptr(/* using correct args */)
>
> How should I define generic_ptr?


You can't.

> Is (void*) ok?


No.

> It seems to work on my machine,


You got unlucky.

> but I would like to know if this is standard/portable.


It isn't. The most common generic function pointer type
is void (*)(), though that won't cater for variadic
functions. Moreover, you generally need to cast to
and from the original function pointer in order to use
it.

To avoid the casting, it's much more common to make all
your functions have the same prototype. Another
alternative is to use a union type.

--
Peter
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      12-03-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Hi everyone
>
> I am interested in having multiple functions with different prototypes
> and deciding, by setting a pointer, which of them to use later in the
> program.
>
> Eg:
>
> int f1(void);
> char* f2(int);
> /* ... many more of these to choose from */
>
> /* ? correct declaration of generic_ptr ? */
>
> if (/*...*/)
> generic_ptr = f1;
> else
> generic_ptr = f2;


This is not possible, but you can do something like

void (*generic_ptr)();
if (/*...*/)
generic_ptr = (void(*)()) f1;
else
generic_ptr = (void(*)()) f2;

Although I usually consider typedefs for pointer types to be
a Bad Thing, this is one of the exceptions where it seems to
me the readability can be improved a lot:

typedef void (*FuncPtr)();
FuncPtr generic_ptr;
if (/*...*/)
generic_ptr = (FuncPtr)f1;
else
generic_ptr = (FuncPtr)f2;

> generic_ptr(/* using correct args */)


You can *almost* do this, but only if all of your functions
obey some rather strange restrictions:

- All of f1, f2, ... and generic_ptr must return the same
type, or all must be void

AND

- None of f1, f2, ... and generic_ptr can be a variadic
function, or all must be variadic and have the same number
and types of fixed arguments

AND

- If the argument types are omitted (as above), then all the
arguments to all of f1, f2, ... must be non-promotable, or
all of f1, f2, ... must be defined with the obsolescent
"K&R" syntax.

The problem is that the type of the pointer with which you
call a function must agree with the actual type of the function
that is called. The strange restrictions listed above allow you
to skirt the agreement rule just a little bit -- but there's
still no way you can use the same pointer expression to call a
function returning int *and* a function returning double, for
example.

An alternative is to cast at the point of call, which again
is clarified by the use of some typedefs:

typedef int (*IntOfVoid)(void);
typedef char* (*StrOfInt)(int);
if (/*...*/)
i = ((IntOfVoid)generic_ptr)();
else
s = ((StrOfInt)generic_ptr)(42);

> How should I define generic_ptr? Is (void*) ok? It seems to work on my
> machine, but I would like to know if this is standard/portable.


See above. No. Happenstance, and it's not.

If the functions f1, f2, ... really bear no resemblance to
each other you're pretty much doomed to casting -- but in such a
case it's hard to see why you'd want to use a single "generic"
pointer in the first place. If they are related in some way but
differ in details, it may be better to use wrapper functions.
For example, suppose all the functions return int values, all
take two int arguments, and some also take a third string argument.
You could do something like

int f1(int, int, char*);
int f2(int, int, char*);
int f3(int, int); /* only two arguments */

int wrapf3(int x, int y, char* unused) {
return f3(x, y);
}

typedef int (*FuncPtr)(int, int, char*);
FuncPtr fptr;

if (/*...*/)
fptr = f1;
else if (/*...*/)
fptr = f2;
else
fptr = wrapf3; /* note indirection */

printf ("%d\n", fptr(42, 29, "Zaphod Rulez!"));

This technique may appear limiting at first glance, but when
you start applying it to actual "families" of "broadly similar"
functions it works quite well.

--
(E-Mail Removed)
 
Reply With Quote
 
juerg.lemke@yahoo.com
Guest
Posts: n/a
 
      12-03-2007
Eric, Peter

Thank you for the stupendously informative replies.

J
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-04-2007
(E-Mail Removed) writes:
> I am interested in having multiple functions with different prototypes
> and deciding, by setting a pointer, which of them to use later in the
> program.
>
> Eg:
>
> int f1(void);
> char* f2(int);
> /* ... many more of these to choose from */
>
> /* ? correct declaration of generic_ptr ? */
>
> if (/*...*/)
> generic_ptr = f1;
> else
> generic_ptr = f2;
>
> generic_ptr(/* using correct args */)
>
> How should I define generic_ptr? Is (void*) ok? It seems to work on my
> machine, but I would like to know if this is standard/portable.


void* is a generic object pointer type, in the sense that (1) you can
convert any object pointer to void* and back again, and get the
original pointer, and (2) such conversions can be done implicitly
(e.g., by a simple assignment rather than a cast).

There's no guarantee that converting a function pointer to or from
void* will give you anything meaningful. There is no generic function
pointer type in the sense of (2) above; conversions to and from
function pointer types must be explicit. But in the sense of (1),
*all* function pointer types are effectively generic; you can convert
a function pointer to any other function pointer type and back again
and get the same pointer. In effect, all function pointers "smell
alike", something that's not the case for object pointers.

But calling a function via a pointer of the wrong type invokes
undefined behavior.

Your best bet is probably to use something like ``void(*)(void)'',
(use a typedef) but you'll need to explicitly convert to or from this
type. Since there's no runtime representation of types (e.g., you
can't say ``if (typeof(x) == int)''), you'll need to use a switch
statement to select the proper type, and write each type of call
individually.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      12-04-2007
Peter Nilsson wrote:
>

.... snip ...
>
> It isn't. The most common generic function pointer type is
> void (*)(), though that won't cater for variadic functions.
> Moreover, you generally need to cast to and from the original
> function pointer in order to use it.


I believe the standard bans casts to and from function pointers.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      12-04-2007
In article <(E-Mail Removed)>,
CBFalconer <(E-Mail Removed)> wrote:
>Peter Nilsson wrote:
>>

>... snip ...
>>
>> It isn't. The most common generic function pointer type is
>> void (*)(), though that won't cater for variadic functions.
>> Moreover, you generally need to cast to and from the original
>> function pointer in order to use it.


>I believe the standard bans casts to and from function pointers.


Casting between different function pointer types is explicitly
permitted; using the result is left undefined unless it matches
the actual call.

If I recall correctly, casting between a function pointer and an
object pointer (or the other way) is not banned, and that C
implementations are permitted to assign semantics to the result,
but the semantics are not specified in the C standards.

It -is- the case that the description of the semantics of
casting pointers takes care to group object pointers seperately from
function pointers. It is one of those clauses that is easy to
mis-read, in the sense that one's expectation (from experience)
that object pointers and function pointers "are" (as far as
one has ever encountered) convertable, can easily lead one to
overlook the seperation and "read in" a convertability that is
not present in the clause. If I had written the relevant paragraph,
I would probably have pointed out the non-covertability rather than
leaving it implied by simply leaving "object types" out of the list.
But then if I -had- written the standard, it probably would have been
four or five times as long as it turned out to be, as conciseness
never has been one of my strong points.
--
"Any sufficiently advanced bug is indistinguishable from a feature."
-- Rich Kulawiec
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      12-04-2007
Walter Roberson wrote:

> If I recall correctly, casting between a function pointer and an
> object pointer (or the other way) is not banned, and that C
> implementations are permitted to assign semantics to the result,
> but the semantics are not specified in the C standards.


That's what "undefined" means.

Implementations are permitted to assign semantics
to the result of (1 / 0) also.

--
pete
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-04-2007
pete <(E-Mail Removed)> writes:
> Walter Roberson wrote:
>> If I recall correctly, casting between a function pointer and an
>> object pointer (or the other way) is not banned, and that C
>> implementations are permitted to assign semantics to the result,
>> but the semantics are not specified in the C standards.

>
> That's what "undefined" means.


Yes, but the previous poster had speculated that such casts are
"banned". They aren't.

> Implementations are permitted to assign semantics
> to the result of (1 / 0) also.


True.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
jameskuyper@verizon.net
Guest
Posts: n/a
 
      12-04-2007
CBFalconer wrote:
> Peter Nilsson wrote:
> >

> ... snip ...
> >
> > It isn't. The most common generic function pointer type is
> > void (*)(), though that won't cater for variadic functions.
> > Moreover, you generally need to cast to and from the original
> > function pointer in order to use it.

>
> I believe the standard bans casts to and from function pointers.


You believe incorrectly. Section 6.3.2.3p8:
" A pointer to a function of one type may be converted to a pointer to
a function of another
type and back again; the result shall compare equal to the original
pointer."
 
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
pointer to an array vs pointer to pointer subramanian100in@yahoo.com, India C Programming 5 09-23-2011 10:28 AM
Pointer to pointer or reference to pointer A C++ 7 07-05-2011 07:49 PM
Pointer to pointer Vs References to Pointer bansalvikrant@gmail.com C++ 4 07-02-2009 10:20 AM
passing the address of a pointer to a func that doesnt recieve a pointer-to-a-pointer jimjim C Programming 16 03-27-2006 11:03 PM
Pointer-to-pointer-to-pointer question masood.iqbal@lycos.com C Programming 10 02-04-2005 02:57 AM



Advertisments