int
scrollmenul(orgy, orgx, title, maxrows)
char *title;
{
char *choices[MAX_LIST_SIZE], **cpp;
va_list argp;
cpp = choices;
va_start(argp, maxrows);
while (*cpp++ = va_arg(argp, char *))
;
return scrollmenuv(orgy, orgx, title, maxrows, choices);
}
--
Email: cyr...@hotmail.com
(supporter of the campaign against grumpiness in c.l.c)
"Light thinks it travels faster than anything but it is wrong.
No matter how fast light travels it finds that darkness has always
got there first, and is waiting for it." --Terry Pratchett
Thanks. Can I mix declaration syntaxes? I seem to remember hearing you
can't. If I only need to change functions that use variable arguments,
this is a minor change. If I have to change every function, I have a
big project on my hands.
In article <35C7B099...@juno.com> Cyrand <cyr...@juno.com> wrote:
>Thanks. Can I mix declaration syntaxes?
Yes. You can also mix prototype declarations with old-style
definitions, e.g.,
int f1(int, char *);
int f2(void);
int
f1(i, p)
int i;
char *p;
{
/* ... */
return 17;
}
int
f2()
{
/* ... */
return 42;
}
You must, however, be aware of several restrictions. First, all
variable-arguments functions must be prototyped, and their definitions
must use the newfangled 1989 prototype definition format (as James
Hu mentioned). Second, old-style function definitions do not provide
prototypes and need not be verified against the prototype, so that,
for instance:
int f3(int);
int f3(p) char *p; { return *p; }
need not draw a diagnostic (despite being obviously broken). Third
and probably most tricky, you must widen all the arguments according
to "the usual arithmetic conversions": char and short become int,
and float becomes double. This means that the correct prototype
for a function *defined* as:
void
f4(c, x)
char c;
float x;
{
/* ... */
}
is:
void f4(int, double);
and *not* the obvious but wrong "void f4(char, float)".
The fact that you can mix these means that you can do the following:
#ifdef USE_PROTOTYPES
#define PROTO(args) args
#else
#define PROTO(args) ()
#endif
int f1 PROTO((int, char *));
int f2 PROTO((void));
int f3 PROTO((int));
int f4 PROTO((int, double));
This kind of PROTO macro (sometimes spelled just "P", or in
implementation-specific headers like those in 4.4BSD's /usr/include
directory, __P) allows you to get the benefits of prototypes while
still being able to compile on creaky old pre-1990 systems.
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA Domain: to...@bsdi.com +1 510 234 3167
Antispam notice: unsolicited commercial email will be handled at my
consulting rate; pyramid-scheme mail will be forwarded to the FTC.
int
scrollmenul (int orgy, int orgx, char *title, int maxrows, ...)
{
char *choices[MAX_LIST_SIZE], **cpp;
va_list argp;
cpp = choices;
va_start(argp, maxrows);
while ((*cpp++ = va_arg(argp, char *)))
;
va_end (argp);
return scrollmenuv(orgy, orgx, title, maxrows, choices);
}
The only things that made the code non-conforming were the lack of
"..." and the missing call to va_end(). Putting the "..." into the
function made it necessary to use the improved ANSI C function
declaration syntax.
I also added an extra pair of parentheses around the test condition to
quiet a warning.
The K&R C did not have a syntax for declaring functions with variable
arguments.
--
James C. Hu <j...@cs.wustl.edu> Computer Science Doctoral Candidate
http://www.cs.wustl.edu/~jxh/ Washington University in Saint Louis
>>>>>>>>>>>>> I use *SpamBeGone* <URL:http://www.internz.com/SpamBeGone/>
>> ... Putting the "..." into the function made it necessary to use the
>> improved ANSI C function declaration syntax. ...
>Thanks. Can I mix declaration syntaxes? ...
A guarded yes. The gotcha's generally involve mixing oldstyle function
prototypes with the improved style for the same function.
int scrollmenul(int orgy, int orgx, char *title, int maxrows,...)
{
char *choices[MAX_LIST_SIZE], **cpp;
va_list argp;
cpp = choices;
va_start(argp, maxrows);
while ((*cpp++ = va_arg(argp, char *))) ;
va_end(argp);
return scrollmenuv(orgy, orgx, title, maxrows, choices);
}
Martin Ambuhl (mam...@tiac.net)
/* Newsgroup posts also e-mailed */
...
>You must, however, be aware of several restrictions. First, all
>variable-arguments functions must be prototyped, and their definitions
>must use the newfangled 1989 prototype definition format (as James
>Hu mentioned). Second, old-style function definitions do not provide
>prototypes and need not be verified against the prototype, so that,
>for instance:
>
> int f3(int);
> int f3(p) char *p; { return *p; }
>
>need not draw a diagnostic (despite being obviously broken).
I believe a diagnostic is required here. 6.5 has a constraint that
declarations in the same scope that refer to the same object or function
specify compatible types. 6.5.4.3 is clear that these don't have
compatible types. The main problem with K&R style declarations and
definitions is that there is no enforced argument type checking in function
calls.
>Third and probably most tricky, you must widen all the arguments according
>to "the usual arithmetic conversions": char and short become int,
>and float becomes double.
These are the default argument promotions (6.3.2.2). The usual arithmetic
conversions are a set of rules to bring two arithmetic operands to a
common type. Both make use of the integral promotions. I think I've just
about reached the stage where I don't mix them up but relapse is always
possible. :-)
--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------