473,785 Members | 2,879 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 5681
Tor Rustad <to********@hot mail.comwrites:
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.
As Keith Thompson's message points out, assignment-like contexts
provide enough type information that C *could* allow the conversion
from one function type to another without a cast.

Just to be clear, I was focusing on the function call. At that point,
there is not enough information for the compiler to generate a correct
call, at least not in the most general case.
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.
Anything that requires a run-time check seems to run counter to the
spirit of C.

--
Ben.
Jun 27 '08 #21
Malcolm McLean wrote:
>
"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. You can
hardcode
I beg to differ:
http://www.haible.de/bruno/packages-ffcall.html

Sure, it's not implemented purely in C, but that doesn't matter:
It provides a C interface to build argument lists on the fly.
Personally I make heavy use of it in adapting script
interpreters to C modules.

Wolfgang Draxinger
--
E-Mail address works, Jabber: he******@jabber .org, ICQ: 134682867

Jun 27 '08 #22
In article <bk************ @darkstargames. dnsalias.net>,
Wolfgang Draxinger <wd********@dar kstargames.dewr ote:
>Malcolm McLean wrote:
>>
"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. You can
hardcode

I beg to differ:
http://www.haible.de/bruno/packages-ffcall.html

Sure, it's not implemented purely in C, but that doesn't matter:
It provides a C interface to build argument lists on the fly.
Personally I make heavy use of it in adapting script
interpreters to C modules.
Yes. I have mentioned ffcall (aka, avcall) many times here. It is very
nice. But, of course, the regs aren't interested.

Jun 27 '08 #23
Ben Bacarisse skrev:
Tor Rustad <to********@hot mail.comwrites:
>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.

As Keith Thompson's message points out, assignment-like contexts
provide enough type information that C *could* allow the conversion
from one function type to another without a cast.
Keith's point appeared meaningless to me, because today we are forced to
do a cast, and by doing so, we shut down type checks.

Hence, if there was a generic function pointer, the matter will not get
worse, since implementations can add type-safety checks which don't need
to be shut down by such a cast.

Just to be clear, I was focusing on the function call. At that point,
there is not enough information for the compiler to generate a correct
call, at least not in the most general case.
The compiler can very much generate the correct call, BUT it's a
different matter if such a function exist, and this is the job of the
run-time loader to detect.

It a QoI issue, how well a run-time loader does this job.

>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.

Anything that requires a run-time check seems to run counter to the
spirit of C.
Checks are already needed today by the run-time loader. This isn't
rocket science, on implementations supporting dynamically loadable
libraries, the run-time loaders typically locate functions via symbolic
search.

Now, by decorating the exported function symbols, type-safety can be
added for explicit linking, without any significant extra overhead
compared with what there is already.

I'm aware that symbols can be stripped, but that is like instructing the
compiler to export functions in a library with a cast, and just make
function relative addresses visible to the world outside.

--
Tor <bw****@wvtqvm. vw | tr i-za-h a-z>
Jun 27 '08 #24
Wolfgang Draxinger <wd********@dar kstargames.dewr ites:
Malcolm McLean wrote:
>"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. You can
hardcode

I beg to differ:
http://www.haible.de/bruno/packages-ffcall.html

Sure, it's not implemented purely in C, but that doesn't matter:
It provides a C interface to build argument lists on the fly.
Personally I make heavy use of it in adapting script
interpreters to C modules.
But be careful. Quoting the "Bugs" section of the avcall man page:

* The current implementations have been tested on a selection of
common cases but there are probably still many bugs.

* There are typically built-in limits on the size of the
argument-list, which may also include the size of any structure
arguments.

* The decision whether a struct is to be returned in registers or
in memory considers only the struct's size and alignment. This
is inaccurate: for example, gcc on m68k-next returns struct {
char a,b,c; } in registers and struct { char a[3]; } in memory,
although both types have the same size and the same alignment.

I don't believe it's possible to do what avcall does in entirely
portable C. If the benefits outweigh the limitations for your
particular use, that's fine.

--
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 #25
In article <2L************ *********@telen or.com>,
Tor Rustad <to********@hot mail.comwrote:
>What a C programmer want, is to be able to load libraries/modules and
symbols dynamically, and do so without a cast.
We do???

I don't recall a single instance in which I found providing
the cast to be a burden.
--
"What we have to do is to be forever curiously testing new
opinions and courting new impressions." -- Walter Pater
Jun 27 '08 #26
In article <5b************ *********@telen or.com>,
Tor Rustad <to********@hot mail.comwrote:
....
>
Keith's point appeared meaningless to me, because today we are forced to
do a cast, and by doing so, we shut down type checks.
Most of Keith's posts are (totally) meaningless. But they are always
fun to read, and, in fact, I now explicitly do a "select" (in my
"killfile") on articles written by him.

Jun 27 '08 #27
>Wolfgang Draxinger <wd********@dar kstargames.dewr ites:
>Sure, it's not implemented purely in C ...
Significant pieces are not in C at all :-)

In article <ln************ @nuthaus.mib.or g>
Keith Thompson <ks***@mib.orgw rote:
>I don't believe it's possible to do what avcall does in entirely
portable C. ...
Indeed not. (But if what it does do, non-portably, is good enough
for what you want done, that is obviously sufficient. The time to
worry is when you need it to do more, or to work on another machine.
It should always be possible to make it work there, but it may take
some effort, and possibly modifications to whatever code you have
that uses avcall as well as to avcall itself.)

Here is an example of part of the code (I do not know why it
has its own private offsetof when the <stdlib.hversio n should
work here):

#include "avcall.h.i n"

#define RETURN(TYPE,VAL ) (*(TYPE*)l->raddr = (TYPE)(VAL))
#define OFFSETOF(struct ,member) ((int)&(((struc t*)0)->member))

register void* callee __asm__("%g2"); /* any global or local register */
register __avword o0 __asm__("%o0");
register __avword o1 __asm__("%o1");
register __avword o2 __asm__("%o2");
register __avword o3 __asm__("%o3");
register __avword o4 __asm__("%o4");
register __avword o5 __asm__("%o5");

int
__builtin_avcal l(av_alist* l)
{
register __avword* sp __asm__("%sp"); /* C names for registers */
register float fret __asm__("%f0"); /* %f0 */
register double dret __asm__("%f0"); /* %f0,%f1 */

__avword trampoline[6]; /* room for a trampoline */
__avword space[__AV_ALIST_WORD S]; /* space for callee's stack frame */
__avword *argframe = sp + 17; /* stack offset for argument list */
int arglen = l->aptr - l->args;
__avword i;

if (l->farg_mask) {
/* push leading float args */
if (l->farg_mask & (1<<0))
__asm__("ld %1(%0),%%f1" : : "p" (l), "i" OFFSETOF(av_ali st,args[0]));
[rest snipped]

This is not only gcc-specific, it also does not compile on your%
machine, even if you have gcc. :-) It is not really C code at
all, but rather assembly code with a C skeleton.

(Of course, there is a different version for your% machine.)

[% By "your" I mean "you, the person reading this news article".
There may be a few rare readers -- perhaps Eric Sosman, for instance
-- for whom this statement is untrue, though.]
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
Jun 27 '08 #28
Tor Rustad <to********@hot mail.comwrites:
Ben Bacarisse skrev:
>Tor Rustad <to********@hot mail.comwrites:
>>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.

As Keith Thompson's message points out, assignment-like contexts
provide enough type information that C *could* allow the conversion
from one function type to another without a cast.

Keith's point appeared meaningless to me, because today we are forced
to do a cast, and by doing so, we shut down type checks.

Hence, if there was a generic function pointer, the matter will not
get worse, since implementations can add type-safety checks which
don't need to be shut down by such a cast.
I am getting confused as to what point you want to make. Maybe you
should give an example. I wrote a lot then deleted it because I think
we are talking at cross purposes. What would like to see that would help?
>Just to be clear, I was focusing on the function call. At that point,
there is not enough information for the compiler to generate a correct
call, at least not in the most general case.

The compiler can very much generate the correct call, BUT it's a
different matter if such a function exist, and this is the job of the
run-time loader to detect.
I was making a narrow technical point: given a generic function
pointer type, a C function call does not have the information required
to check the type and generate the correct calling code. Assume fp is
such a generic pointer. What is the type of function being called
here:

fp(12.3);

The compiler might have to generate different code depending on whether
fp points to void fd(double) {...} or void fi(int) {...}.

Of course, if the real type of the pointed-to function is carried
around at run-time the correct call can be made, but that is not in the
spirit of C.

--
Ben.
Jun 27 '08 #29
Chris Torek wrote:
Here is an example of part of the code (I do not know why it
has its own private offsetof when the <stdlib.hversio n should
work here):
<stddef.hversio n

offsetof is portable for freestanding
as well as hosted implementations .

--
pete
Jun 27 '08 #30

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
9645
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
9480
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10329
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
10152
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
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
3650
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.