Connecting Tech Pros Worldwide Forums | Help | Site Map

Casting pointers to varargs functions

Gene
Guest
 
Posts: n/a
#1: Nov 3 '07
Hello all. Is the initializing assignment below ANSI standard-
conforming?

Is there a way to have the prefix parameters to ... type checked in
such an assignment? E.g. in this case int x in the typedef matched
with int a of foo?

Appreciate the help.

------------

#include <stdio.h>

int foo(int a, int b)
{
return a + b;
}

typedef int (*FUNCTION)(int x, ...);

int main(void)
{
FUNCTION p = (FUNCTION)foo;
printf("%d\n", (*p)(1, 2));
return 0;
}

Eric Sosman
Guest
 
Posts: n/a
#2: Nov 3 '07

re: Casting pointers to varargs functions


Gene wrote:
Quote:
Hello all. Is the initializing assignment below ANSI standard-
conforming?
Yes, but ...
Quote:
Is there a way to have the prefix parameters to ... type checked in
such an assignment? E.g. in this case int x in the typedef matched
with int a of foo?
Yes, the fixed parameters behave like normal prototyped
parameters, but ...
Quote:
Appreciate the help.
>
------------
>
#include <stdio.h>
>
int foo(int a, int b)
{
return a + b;
}
>
typedef int (*FUNCTION)(int x, ...);
>
int main(void)
{
FUNCTION p = (FUNCTION)foo;
printf("%d\n", (*p)(1, 2));
... but right here your program goes off the rails. The
function pointer type ("pointer to function returning int,
taking an int and variable arguments") does not match the type
of the called function ("function returning int, taking two
int arguments"). When you call a function via a pointer that
doesn't match the function's actual type, the behavior is
undefined.

It's not a matter of caprice. Different machines use
different mechanisms for subroutine linkage, and the "normal"
argument passing mechanism may be unsuitable for variable
argument lists. For example, imagine a machine with separate
CPU registers for integer and floating-point values; a call
to `foo(int x, double y, int z)' might use R0 and R1 for x
and z, and F0 for y. But this convention could be clumsy for
`bar(int q, ...)' even if the remaining arguments in some call
turn out to be a double and an int. An implementation might
invoke bar by passing q in R0 and a pointer to a memory-resident
aggregation of the remaining arguments in R1. If the caller
uses one convention and the callee uses something else, then
"What we have here is a failure to communicate."

--
Eric Sosman
esosman@ieee-dot-org.invalid
Gene
Guest
 
Posts: n/a
#3: Nov 3 '07

re: Casting pointers to varargs functions


On Nov 2, 9:57 pm, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
Quote:
Gene wrote:
Quote:
Hello all. Is the initializing assignment below ANSI standard-
conforming?
>
Yes, but ...
>
Quote:
Is there a way to have the prefix parameters to ... type checked in
such an assignment? E.g. in this case int x in the typedef matched
with int a of foo?
>
Yes, the fixed parameters behave like normal prototyped
parameters, but ...
>
>
>
Quote:
Appreciate the help.
>
Quote:
------------
>
Quote:
#include <stdio.h>
>
Quote:
int foo(int a, int b)
{
return a + b;
}
>
Quote:
typedef int (*FUNCTION)(int x, ...);
>
Quote:
int main(void)
{
FUNCTION p = (FUNCTION)foo;
printf("%d\n", (*p)(1, 2));
>
... but right here your program goes off the rails. The
function pointer type ("pointer to function returning int,
taking an int and variable arguments") does not match the type
of the called function ("function returning int, taking two
int arguments"). When you call a function via a pointer that
doesn't match the function's actual type, the behavior is
undefined.
>
It's not a matter of caprice. Different machines use
different mechanisms for subroutine linkage, and the "normal"
argument passing mechanism may be unsuitable for variable
argument lists. For example, imagine a machine with separate
CPU registers for integer and floating-point values; a call
to `foo(int x, double y, int z)' might use R0 and R1 for x
and z, and F0 for y. But this convention could be clumsy for
`bar(int q, ...)' even if the remaining arguments in some call
turn out to be a double and an int. An implementation might
invoke bar by passing q in R0 and a pointer to a memory-resident
aggregation of the remaining arguments in R1. If the caller
uses one convention and the callee uses something else, then
"What we have here is a failure to communicate."
>
--
Eric Sosman
esos...@ieee-dot-org.invalid
Thanks Eric. That's just what I need and sort of what I expected.
What if I say instead

typedef int (*FUNCTION)();

? I.e. use no prototype at all for the parameters a la K&R. Is this
now reliable?

(Interesting that gcc doesn't complain about the first first form even
with -Wall --ansi --pedantic.)


Ian Collins
Guest
 
Posts: n/a
#4: Nov 3 '07

re: Casting pointers to varargs functions


Gene wrote:
Quote:
On Nov 2, 9:57 pm, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
Quote:
>>
> It's not a matter of caprice. Different machines use
>different mechanisms for subroutine linkage, and the "normal"
>argument passing mechanism may be unsuitable for variable
>argument lists. For example, imagine a machine with separate
>CPU registers for integer and floating-point values; a call
>to `foo(int x, double y, int z)' might use R0 and R1 for x
>and z, and F0 for y. But this convention could be clumsy for
>`bar(int q, ...)' even if the remaining arguments in some call
>turn out to be a double and an int. An implementation might
>invoke bar by passing q in R0 and a pointer to a memory-resident
>aggregation of the remaining arguments in R1. If the caller
>uses one convention and the callee uses something else, then
>"What we have here is a failure to communicate."
>>
*Please* don't quote signatures...
Quote:
>
Thanks Eric. That's just what I need and sort of what I expected.
What if I say instead
>
typedef int (*FUNCTION)();
>
? I.e. use no prototype at all for the parameters a la K&R. Is this
now reliable?
>
If what context? IIRC if you use a K&R style prototype, any parameters
passed will be promoted to int, which might not be what you want.
Quote:
(Interesting that gcc doesn't complain about the first first form even
with -Wall --ansi --pedantic.)
>
Not at all, you told it not to complain with that horrible cast!

--
Ian Collins.
Ben Pfaff
Guest
 
Posts: n/a
#5: Nov 3 '07

re: Casting pointers to varargs functions


Ian Collins <ian-news@hotmail.comwrites:
Quote:
If what context? IIRC if you use a K&R style prototype, any parameters
passed will be promoted to int, which might not be what you want.
Point of terminology: "K&R style prototype" is a contradiction in
terms. You can have a declaration that is not a prototype, and
I'd even allow that you can have a K&R-style function definition,
but you can't have a K&R style prototype.
--
Ben Pfaff
http://benpfaff.org
Ian Collins
Guest
 
Posts: n/a
#6: Nov 3 '07

re: Casting pointers to varargs functions


Ben Pfaff wrote:
Quote:
Ian Collins <ian-news@hotmail.comwrites:
>
Quote:
>If what context? IIRC if you use a K&R style prototype, any parameters
>passed will be promoted to int, which might not be what you want.
>
Point of terminology: "K&R style prototype" is a contradiction in
terms. You can have a declaration that is not a prototype, and
I'd even allow that you can have a K&R-style function definition,
but you can't have a K&R style prototype.
Fair point.

--
Ian Collins.
Closed Thread


Similar C / C++ bytes