473,785 Members | 2,829 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why no generic function pointers?

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. In fact, it seems to be quite
"irregular" to me that you can't cast function pointers to void.

I mean, of course, generic function pointers are "dangerous" , because they allow
you to call a function with bad arguments and the compiler can't detect that.
But it's not any more "dangerous" than unsigned char pointers to any type of data i.e.
not against the "C spirit" IMO.

In fact, K&R compilers supported semi-generic function pointers IIRC. You were
able to leave out the parameter declaration (but not the return type declaration) e.g.
int (*foo)();

So why did the comittee decide against making generic function pointers standard?

Jun 27 '08
32 5680

"Ben Bacarisse" <be********@bsb .me.ukwrote in message
news:87******** ****@bsb.me.uk. ..
"Malcolm McLean" <re*******@btin ternet.comwrite s:
>"copx" <co**@gazeta.pl wrote in message
>>Why doesn't the C standard include generic function pointers?
Because you can't build an argument list on the fly.

That begs the question of why one can't do *that*. There are macros
to examine an existing var-arg list, and there the could be macros to
build one from scratch. Given such a thing, a function pointer type
like:

void *(*var_arg_fp)( void *, ...);

would be very flexible (you need a dummy first argument to get the var
arg macros going).
How would that work? Suppose I have my function pointer fnptr. And I have N
(known only at runtime) arguments from an array, say, to pass it. How can I
have a loop pushing just the parameters I need?

I have an actual need for this; at the moment I'm doing stuff like this
(assume fn is a valid function call):

switch (N) {
case 0: result=fn(); break;
case 1: result=fn(param s[0]); break;
case 2: result=fn(param s[0],params[1]); break;
...
up to some limit.

(and the whole thing repeated for different calltypes of fn; and repeated
again for different return type of fn: int-sized or double)

This works; and is not necessarily slower than a loop, but it's clumsy and
does have an arbitrary upper limit on parameters.

--
Bartc
Jun 27 '08 #11
"Bartc" <bc@freeuk.comw rote in message news:
>
"Ben Bacarisse" <be********@bsb .me.ukwrote in message
>>
void *(*var_arg_fp)( void *, ...);

would be very flexible (you need a dummy first argument to get the var
arg macros going).

How would that work? Suppose I have my function pointer fnptr. And I have
N (known only at runtime) arguments from an array, say, to pass it. How
can I have a loop pushing just the parameters I need?
Ben's nodded.

What you need is a macro to build a va_arg list

va_arg_add(argl ist, type, argument)

so user passes a string like "ipippiii" where i means an integer argument
and p a char * (to make it simple). We iterate over the string, putting in
integers and character pointers, then we call the user-supplied function
pointer.

To help out the compiler a bit we could specify that the user-defined
function must be varidic.

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

Jun 27 '08 #12

"Malcolm McLean" <re*******@btin ternet.comwrote in message
news:X8******** *************** *******@bt.com. ..
"Bartc" <bc@freeuk.comw rote in message news:
>>
"Ben Bacarisse" <be********@bsb .me.ukwrote in message
>>>
void *(*var_arg_fp)( void *, ...);

would be very flexible (you need a dummy first argument to get the var
arg macros going).

How would that work? Suppose I have my function pointer fnptr. And I have
> N (known only at runtime) arguments from an array, say, to pass it.
How
can I have a loop pushing just the parameters I need?
Ben's nodded.

What you need is a macro to build a va_arg list

va_arg_add(argl ist, type, argument)

so user passes a string like "ipippiii" where i means an integer argument
and p a char * (to make it simple). We iterate over the string, putting in
integers and character pointers, then we call the user-supplied function
pointer.
That looks like a compile-time process to me.

Just consider the possible implementation of this simplified function
interface:

int callfunction (void *fnptr, int nparams, int *params);

'params' points to a list of int values to be passed.

'nparams' is how many ints there are in 'params'.

The task is to call fnptr with the parameters as specified, and to return
what fnptr returns (I know I haven't fully specified it's signature but
assume the return value is int).

--
Bartc

Jun 27 '08 #13
"Bartc" <bc@freeuk.comw rote in message news
>
"Malcolm McLean" <re*******@btin ternet.comwrote in message
>so user passes a string like "ipippiii" where i means an integer argument
and p a char * (to make it simple). We iterate over the string, putting
in
integers and character pointers, then we call the user-supplied function
pointer.

That looks like a compile-time process to me.
No, the string could be generated anyhow. Imagine this not-too unrealistic
scenario.

You want the user to type "printf("%d%s\n ", 10, "Fred")"
You want the program to call printf() or vprintf() with the arguments he
supplied.

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


Jun 27 '08 #14
copx skrev:
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.
Notice however, that the return type of the POSIX XSI dlsym() function
is a void pointer, and in the X/Open System Interface Extension

http://www.opengroup.org/onlinepubs/...ons/dlsym.html

we find:

"Implementation s supporting the XSI extension, however, do require that
an object of type void * can hold a pointer to a function."
In practice, I have yet to run into an implementation where function
pointer couldn't be converted to void *, and back. So instead of asking
for a generic function pointer, I find the XSI requirement "type void *
can hold a pointer to a function" more natural thing to ask for.

--
Tor <bw****@wvtqvm. vw | tr i-za-h a-z>
Jun 27 '08 #15
Eric Sosman skrev:

[...]
>
And in strictly-conforming C you can cast any function pointer
to any other function pointer type and back again. What's your beef?

Sure can, but isn't a cast needed?
OTOH, a cast isn't needed to void* convert to another
(pointer-to-object) type.
--
Tor <bw****@wvtqvm. vw | tr i-za-h a-z>
Jun 27 '08 #16
"Bartc" <bc@freeuk.comw rites:
"Ben Bacarisse" <be********@bsb .me.ukwrote in message
news:87******** ****@bsb.me.uk. ..
>"Malcolm McLean" <re*******@btin ternet.comwrite s:
>>"copx" <co**@gazeta.pl wrote in message
Why doesn't the C standard include generic function pointers?

Because you can't build an argument list on the fly.

That begs the question of why one can't do *that*. There are macros
to examine an existing var-arg list, and there the could be macros to
build one from scratch. Given such a thing, a function pointer type
like:

void *(*var_arg_fp)( void *, ...);

would be very flexible (you need a dummy first argument to get the var
arg macros going).

How would that work?
I think Malcolm has covered this but it seems there may have been a
misunderstandin g so let me jump in...
Suppose I have my function pointer fnptr. And I have N
(known only at runtime) arguments from an array, say, to pass it. How can I
have a loop pushing just the parameters I need?

I have an actual need for this; at the moment I'm doing stuff like this
(assume fn is a valid function call):

switch (N) {
case 0: result=fn(); break;
case 1: result=fn(param s[0]); break;
case 2: result=fn(param s[0],params[1]); break;
...
up to some limit.

(and the whole thing repeated for different calltypes of fn; and repeated
again for different return type of fn: int-sized or double)
My suggestion does not help in this sort of case. In your case, I
would have been inclined to make fn of type

int (*ifunction)(si ze_t n, int *args);

and thus the call becomes simply 'result = fn(N, params);'. Of course
you may have been constrained in that the functions already exist and
you didn't want to wrap them. If that was the case, neither the above,
nor my varargs suggestion will be of any help.

My suggestion, of building a va_list, is of very limited use. There
are almost always better ways to do it, but it would allow simple
wrappers round the various va_list taking function to be used as
built-in functions in table-driven interpreted languages. Since it is
of limited utility, it is unlikely to become available so the
discussion is largely for entertainment value only.

--
Ben.
Jun 27 '08 #17
Tor Rustad <to********@hot mail.comwrites:
Eric Sosman skrev:

[...]
> And in strictly-conforming C you can cast any function pointer
to any other function pointer type and back again. What's your beef?

Sure can, but isn't a cast needed?

OTOH, a cast isn't needed to void* convert to another
(pointer-to-object) type.
Forgive me if I have got the wrong end of the stick, but you seem to
be suggesting it would be nice if the cast on function pointers (or
void *s where that is supported as an extension) could be avoided. I
can't see how it could be. If the type is not already exactly right,
the required type can not be inferred from the rules C has.

Maybe your "beef" is that you wish the rules were different and the
required type of the pointer could simply be deduced from the call.
If so, then I think you are asking for quite a different language.

--
Ben.
Jun 27 '08 #18
Ben Bacarisse <be********@bsb .me.ukwrites:
Tor Rustad <to********@hot mail.comwrites:
>Eric Sosman skrev:
[...]
>> And in strictly-conforming C you can cast any function pointer
to any other function pointer type and back again. What's your beef?

Sure can, but isn't a cast needed?

OTOH, a cast isn't needed to void* convert to another
(pointer-to-object) type.

Forgive me if I have got the wrong end of the stick, but you seem to
be suggesting it would be nice if the cast on function pointers (or
void *s where that is supported as an extension) could be avoided. I
can't see how it could be. If the type is not already exactly right,
the required type can not be inferred from the rules C has.

Maybe your "beef" is that you wish the rules were different and the
required type of the pointer could simply be deduced from the call.
If so, then I think you are asking for quite a different language.
If the cast were not required for converting function pointer types,
in the same manner that it's not required for void*, then you could do
an implicit conversion via an assignment (or, equivalently, an
initialization or passing an argument). A function call just isn't
one of the assignment-like contexts where there's enough information
to determine the target type (and it happens to be the context where
the conversion would be most useful).

On the other hand, if such an implicit conversion *were* possible, it
would be way too easy to violate type safety in indirect function
calls.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #19
Ben Bacarisse skrev:

Maybe your "beef" is that you wish the rules were different and the
required type of the pointer could simply be deduced from the call.
If so, then I think you are asking for quite a different language.
The standard is silent on issues regarding compile-time and run-time
linking.
What a C programmer want, is to be able to load libraries/modules and
symbols dynamically, and do so without a cast.
i don't see why this require a different language. It is not impossible
to put the burdon on implementations on providing _some_ run-time checks
for type-safety -- in case a generic function pointer was to be used in
such a context.
--
Tor <bw****@wvtqvm. vw | tr i-za-h a-z>
Jun 27 '08 #20

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

Similar topics

28
16463
by: Peter Olcott | last post by:
I want to make a generic interface between a scripting language and native code, the native code and the interpreter will both be written in C++. The interpreter will probably be implemented as a subset of C/C++, thus will have the same syntax as C/C++. Somehow the interpreted code must be able to store generic function pointers because there is no way for the interpreter to know every possible function signature in advance. I was...
0
1385
by: inquisitive | last post by:
Is it possible to have a vector of generic function pointers? I am able to devise a generic function pointer, this way: template <typename elemType, elemType (*function)(std::string&)> struct Method { inline elemType operator()(std::string & property) { return function(property);
1
1369
by: inquisitive | last post by:
Is there a way to create a collection of Method objects, for example a vector or a list? template <typename elemType> struct Method { bool (*function)(elemType&); template <typename elemType> inline bool operator()(elemType & property)
0
10327
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
10151
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
10092
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
9950
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
8973
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...
1
7499
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6740
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4053
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
3647
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.