473,839 Members | 1,726 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

*generic* pointer to function(s)?

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
Dec 3 '07 #1
7 3386
ju*********@yah oo.com 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)(vo id);
typedef char* (*StrOfInt)(int );
if (/*...*/)
i = ((IntOfVoid)gen eric_ptr)();
else
s = ((StrOfInt)gene ric_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.

--
Er*********@sun .com
Dec 3 '07 #2
Eric, Peter

Thank you for the stupendously informative replies.

J
Dec 3 '07 #3
ju*********@yah oo.com 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_Keit h) <ks***@mib.or g>
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"
Dec 4 '07 #4
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
Dec 4 '07 #5
pete <pf*****@mindsp ring.comwrites:
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
implementation s 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_Keit h) <ks***@mib.or g>
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"
Dec 4 '07 #6
<ju*********@ya hoo.comwrote in message
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 */
Don't go down this route.
Building an argument list at runtime is one of the very few operations that
C will not allow you to do.
You can cast to and from void (*fptr)(void) s and any other type on almost
every architecture, but that avails you little if you are then going to
hardcode the calls. You might as well do the job properly and use a union.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Dec 4 '07 #7
Malcolm McLean wrote, On 04/12/07 22:06:
<ju*********@ya hoo.comwrote in message
>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 */
Don't go down this route.
Building an argument list at runtime is one of the very few operations
that C will not allow you to do.
True.
You can cast to and from void (*fptr)(void) s and any other type on
almost every architecture,
You can do it on *every* architecture that has a C compiler because the
C standard says you can do it.
but that avails you little if you are then
going to hardcode the calls. You might as well do the job properly and
use a union.
Whether a union buys you anything will depend on the exact situation.
--
Flash Gordon
Dec 5 '07 #8

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

Similar topics

7
1649
by: Master of C++ | last post by:
Hello Folks, I have a programming dilemma with templates and "genericity". I can think of a few solutions, but I am not sure which one is the best in terms of genetic C++ style. Any suggestions will be greatly appreciated. I am writing a template class Polynomial that encapsulates the functionalities of a Polynomial. Here is a rough sketch for the class:
3
1999
by: Axter | last post by:
I'm wondering about the practical use of dynamic_cast in reusable or generic code. I'm currently working on a smart pointer that can be used on vector and other STL containers. See following link: http://code.axter.com/arr_ptr.h In above code, there's a function called clone_func_ptr_interface within the func_ptr_holder class. In this function, I need to cast from a base pointer to a derived
6
4469
by: aurgathor | last post by:
Howdy, How do I pass some function a generic comparison function? I figured out one non-generic case, but since this code got parameter declarations in two places, it's obviously not generic. TIA #include <stdio.h>
1
1921
by: Albert | last post by:
Hello all, I've got several questions and I'm sure you'll find them easy to answer, but sadly I don't know the answers though: What do people mean by generic pointers Why is a pointer to void generic Why would someone need pointers to void? Thanks
11
4728
by: redefined.horizons | last post by:
First, I would thank all of those that took the time to answer my question about creating an array based on a numeric value stored in a variable. I realize after reading the responses and doing some more research, that what I really need is known in C as a "dynamic array". Basically, you surpass the array notation and use pointers with memory obtained with malloc() or calloc(). I think this will do just what I needed. That has brought...
3
3566
by: markww | last post by:
Hi, I have a wrapper around some 3rd party database library function. The pseudo code looks like the following - it is meant to open a table in a database, extract values from a table, then copy it into my own user defined structures. Since the process of opening and retrieving data from the database is exactly the same for all struct types, and the only part that's different is how the data is copied into the diff structs, I was...
3
1757
by: Frederick Gotham | last post by:
For objects, we have "void*" as the generic pointer type. For instance: enum ParamType { Int, Double }; void Func(void *const p,ParamType const pt) { switch (pt) { case Int: *(int*)p = 42; break; case Double: *(double*)p = 42; break;
1
3436
by: interX | last post by:
Hi I'm new in VC++ and have a question to generics. I have a generic class, which contains an array of the generic type. This array I can pin and then I would like to get an unmanaged pointer to it. Therefore I wanted to creat a class member which represents the pointer to the array. Unfortunately I get the folowring compile error for the code beneath: error C3229: 'DataType *' : indirections on a generic type parameter
32
5690
by: copx | last post by:
Why doesn't the C standard include generic function pointers? I use function pointers a lot and the lack of generic ones is not so cool. There is a common compiler extension (supported by GCC and lccwin32 for example) which I consider to be perfectly reasonable: you can cast every kind of function pointer to a void pointer and void pointers to any kind of function pointer. This follows the general "generics through void scheme" of C....
0
9855
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10588
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
10650
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
10295
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9426
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
5867
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4492
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
4065
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3136
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.