473,407 Members | 2,312 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Casting pointers to varargs functions

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;
}

Nov 3 '07 #1
5 3066
Gene wrote:
Hello all. Is the initializing assignment below ANSI standard-
conforming?
Yes, but ...
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 ...
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
es*****@ieee-dot-org.invalid
Nov 3 '07 #2
On Nov 2, 9:57 pm, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
Gene wrote:
Hello all. Is the initializing assignment below ANSI standard-
conforming?

Yes, but ...
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 ...
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
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.)
Nov 3 '07 #3
Gene wrote:
On Nov 2, 9:57 pm, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
>>
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...
>
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.
(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.
Nov 3 '07 #4
Ian Collins <ia******@hotmail.comwrites:
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
Nov 3 '07 #5
Ben Pfaff wrote:
Ian Collins <ia******@hotmail.comwrites:
>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.
Nov 3 '07 #6

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

Similar topics

1
by: John Silicon | last post by:
Has anyone ever successfully implimented passing member-functions to a varargs function? I thought it would be fairly straight-forward, but seems to come up with nice syntax errors. I've checked...
4
by: Jacob Jensen | last post by:
This question has probably been asked a million time, but here it comes again. I want to learn the difference between the three type cast operators: static_cast, reinterpret_cast, dynamic_cast. A...
2
by: Colin Walters | last post by:
Hi, I have a program which had a little function that always returned TRUE, it looked like this: int always_true_function (void *dummy, ...) { return 1; }
35
by: ytrama | last post by:
Hi, I have read in one of old posting that don't cast of pointer which is returned by the malloc. I would like to know the reason. Thanks in advance, YTR
15
by: XZ | last post by:
Hi everyone, this is really confusing to me: #include <stdio.h> main(int argc, char **argv) { printf("argv = %f\n",(double)atof(argv)); printf("argv = %d\n\n",atoi(argv)); } $ a.out a argv...
14
by: Mirko | last post by:
Hello, I'm new to this list and to Usenet in general, so please forgive (and advice) me, if I do something wrong. Anyway. I am a bit confused, because I always thought one _should_ explicitly...
16
by: Enekajmer | last post by:
Hi, 1 int main() 2 { 3 float a = 17.5; 4 printf("%d\n", a); 5 printf("%d\n", *(int *)&a); 6 return 0; 7 }
28
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...
9
by: Jess | last post by:
Hello, It seems both static_cast and dynamic_cast can cast a base class pointer/reference to a derived class pointer/reference. If so, is there any difference between them? In addition, if I...
32
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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,...
0
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...
0
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...
0
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,...
0
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...

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.