Bill Pursell schrieb:
> I don't particularly enjoy using the va_start macro family, and I've
> noticed that the following code works. I'm a little concerned about
> the fact that the prototypes for foo do not match. Is this safe?
>
> [tmp]$ cat q.c
> extern int foo(int x,...);
>
> int
> main (int argc, char const*const* argv) /*
*/
> {
> foo(0);
> foo(1,
;
> foo(2,3,7);
> foo(4,1,2,3,4);
> return 0;
> }
> [tmp]$ cat r.c
>
> int
> foo(int num, int a, int b, int c)
> {
> switch(num) {
> case 0: return 0;
> case 1: return a;
> case 2: return a+b;
> case 3: return a+b+c;
> default: return -1;
> }
> }
No, this comes into conflict with C99, 6.7.5.3#9 and #15;
you are using incompatible function types.
You are invoking UB.
Let us go for more practical reasons:
- If you do not use int, then you might run into unpleasant
surprises.
int foo(int num, long a, short b, char c)
with LONG_MAX > INT_MAX and sizeof long > sizeof int
int foo(int num, long double a, double b, float c)
both might give you trouble.
- In addition, passing hundred arguments to foo() may be
harmful in quite unexpected ways.
- Another thing: You might have different calling conventions,
maybe only for a certain number of parameters. Merriment ensues
for fixed parameter order.
- Your lint tool or linker warns you about it.
If you really dislike variable argument list handling that much,
then do not use variable argument lists -- you nearly always can
roll an alternative avoiding them at some cost.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.