469,579 Members | 1,782 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,579 developers. It's quick & easy.

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 #1
32 5302
On Sat, 21 Jun 2008 02:54:25 +0200, copx wrote:
Why doesn't the C standard include generic function pointers?
It does, in a way: you can convert (using a cast) a function pointer to a
different function pointer type and back again: the result shall compare
equal to the original pointer. This is similar to the semantics of
void *, except that the conversion is not implicit.
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.
On some systems, function pointers are significantly larger than object
pointers.
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)();
You can still do this.
Jun 27 '08 #2
copx wrote:
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.
And in strictly-conforming C you can cast any function pointer
to any other function pointer type and back again. What's your beef?
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.
If you're irregular, try a laxative.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #3

"Nick Bowler" <dr*****@gmail.comschrieb im Newsbeitrag news:g3**********@rumours.uwaterloo.ca...
On Sat, 21 Jun 2008 02:54:25 +0200, copx wrote:
>Why doesn't the C standard include generic function pointers?

It does, in a way: you can convert (using a cast) a function pointer to a
different function pointer type and back again: the result shall compare
equal to the original pointer. This is similar to the semantics of
void *, except that the conversion is not implicit.
Interesting. Thanks, I didn't know that.


Jun 27 '08 #4

"Eric Sosman" <es*****@ieee-dot-org.invalidschrieb im Newsbeitrag news:Z_******************************@comcast.com. ..
copx wrote:
[snip]
>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.

If you're irregular, try a laxative.
*plonk*
Jun 27 '08 #5
"copx" <co**@gazeta.plwrites:
"Eric Sosman" <es*****@ieee-dot-org.invalidschrieb im Newsbeitrag news:Z_******************************@comcast.com. ..
>copx wrote:
[snip]
>>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.

If you're irregular, try a laxative.

*plonk*
Tons of deliberate personal abuse in this newsgroup, and you plonk
someone over a little joke? I suggest you reconsider -- but if you
don't, it's your loss.

--
Keith Thompson (The_Other_Keith) 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 #6
"copx" <co**@gazeta.plwrites:
Why doesn't the C standard include generic function pointers?
[...]

Remember that there are two distinct ways in which void* is a
"generic" object pointer.

One is that a conversion from foo* to void* and back again is
guaranteed to yield the original value, where foo is any object or
incomplete type. As others have mentioned, *all* function pointers
behave this way. If you want a single generic function pointer type,
I suggest void(*)(void), just because it's the simplest (a typedef
could be helpful).

The other way is that conversions between void* and foo* (foo as
above) may be done implicitly. This isn't the case for function
pointers, but that's just a matter of syntactic convenience.

--
Keith Thompson (The_Other_Keith) 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 #7

"copx" <co**@gazeta.plwrote 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

switch(type)
{
case 1:
x = (*fp)(1,2,3);
break;
case 2:
y = (*fp)("My name is fred");
}

but you can't pass in a format string and build a list with an arbitrary
number of integers and strings.

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

Jun 27 '08 #8
"Malcolm McLean" <re*******@btinternet.comwrites:
"copx" <co**@gazeta.plwrote 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).

I presume the answer is just history. Of course, it may be that there
are real systems for which such argument building macros/functions
would be impossible, but the seems a stretch.

--
Ben.
Jun 27 '08 #9
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
"Malcolm McLean" <re*******@btinternet.comwrites:
>"copx" <co**@gazeta.plwrote 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).

I presume the answer is just history. Of course, it may be that there
are real systems for which such argument building macros/functions
would be impossible, but the seems a stretch.
I think that's right.
Usually any assembly language routine can be translated to C quite easily.
The exception is those assembly routines that build dynamic argument lists.
Normally this is relatively strightforwards in assembly - just push the
first few arguments into registers and the rest on the stack, but you can't
do it in C.

It would tend to open security holes, but I don't think that was the
historical reason for rejecting the idea. Maybe it was because it doesn't
fit well with the structured programming paradigm.

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

Jun 27 '08 #10

"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
"Malcolm McLean" <re*******@btinternet.comwrites:
>"copx" <co**@gazeta.plwrote 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(params[0]); break;
case 2: result=fn(params[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.comwrote 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(arglist, 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*******@btinternet.comwrote in message
news:X8******************************@bt.com...
"Bartc" <bc@freeuk.comwrote 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(arglist, 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.comwrote in message news
>
"Malcolm McLean" <re*******@btinternet.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:

"Implementations 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.comwrites:
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
>"Malcolm McLean" <re*******@btinternet.comwrites:
>>"copx" <co**@gazeta.plwrote 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
misunderstanding 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(params[0]); break;
case 2: result=fn(params[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)(size_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********@hotmail.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********@hotmail.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_Keith) 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
Tor Rustad <to********@hotmail.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.plwrote 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********@darkstargames.dewrote:
>Malcolm McLean wrote:
>>
"copx" <co**@gazeta.plwrote 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********@hotmail.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********@darkstargames.dewrites:
Malcolm McLean wrote:
>"copx" <co**@gazeta.plwrote 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_Keith) 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*********************@telenor.com>,
Tor Rustad <to********@hotmail.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*********************@telenor.com>,
Tor Rustad <to********@hotmail.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********@darkstargames.dewrites:
>Sure, it's not implemented purely in C ...
Significant pieces are not in C at all :-)

In article <ln************@nuthaus.mib.org>
Keith Thompson <ks***@mib.orgwrote:
>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.hversion should
work here):

#include "avcall.h.in"

#define RETURN(TYPE,VAL) (*(TYPE*)l->raddr = (TYPE)(VAL))
#define OFFSETOF(struct,member) ((int)&(((struct*)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_avcall(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_WORDS]; /* 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_alist,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 (4039.22'N, 11150.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********@hotmail.comwrites:
Ben Bacarisse skrev:
>Tor Rustad <to********@hotmail.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.hversion should
work here):
<stddef.hversion

offsetof is portable for freestanding
as well as hosted implementations.

--
pete
Jun 27 '08 #30
Ben Bacarisse skrev:
Tor Rustad <to********@hotmail.comwrites:
>Ben Bacarisse skrev:
[...]
>>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);
Ohh..no

we can't do pointer arithmetic on pointer-to-void either:

void foo(void *p)
{
(*(char *)p)++;
}

so I don't see why you assume I somehow suggest that calling a "generic
function pointer" to be meaningful.
Converting a function pointer to some "generic function pointer", would
throw away information, while converting a "generic function pointer" to
a function pointer, would add information.

I don't see why such conversion should be explicit (i.e. require a
cast), other than as providing a comment for humans (that is, if typedef
of the function pointer is used, else not very readable).
Hmm.. another possibly useful thing with a "generic function pointer",
could be to hold functions (of different types) in a jump table:

gen_func_t jmp[3] = {f1, f2, f3};
Anyway, this is rather academic... in ca. 99,99% IRL cases, void* will
work fine as a generic function pointer. :)

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Jun 27 '08 #31
Tor Rustad <bw****@wvtqvm.vwwrites:
Ben Bacarisse skrev:
>Tor Rustad <to********@hotmail.comwrites:
>>Ben Bacarisse skrev:

[...]
>>>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);

Ohh..no

we can't do pointer arithmetic on pointer-to-void either:

void foo(void *p)
{
(*(char *)p)++;
}

so I don't see why you assume I somehow suggest that calling a
"generic function pointer" to be meaningful.
I wasn't. I was trying to explain what I was saying. It may well
have had nothing to do with what you were saying -- these things
happen on Usenet! That is why I asked for an example of what you
want...
Converting a function pointer to some "generic function pointer",
would throw away information, while converting a "generic function
pointer" to a function pointer, would add information.

I don't see why such conversion should be explicit (i.e. require a
cast), other than as providing a comment for humans (that is, if
typedef of the function pointer is used, else not very readable).
Now I see what you are saying. You want a pointer type to (and from)
which any function pointer can be converted without a cast. This
would help a little, I agree.

I though you were suggesting that the forced cast somehow prevented
some type checking that could otherwise be done.

--
Ben.
Jun 27 '08 #32
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
"Malcolm McLean" <re*******@btinternet.comwrites:
>"copx" <co**@gazeta.plwrote 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).

I presume the answer is just history. Of course, it may be that there
are real systems for which such argument building macros/functions
would be impossible, but the seems a stretch.
For some compilers, functions with varadic argument lists and other function
types can be treated differently.

For instance, I can tell one compiler that I want to pass arguments as
registers when possible. If the function is varadic, then that convention
will not be used (and it will definitely cause problems if a prototype is
not in scope and the warning is ignored).

So I think it is up to the compiler vendor to decide exactly how generic a
pointer to function type might be.
** Posted from http://www.teranews.com **
Jun 27 '08 #33

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.