Interleaved variable argument processing

R

Richard Heathfield

I was recently asked whether it is legal to start processing a variable
argument list a second time, /before/ you've finished with it the first
time. (I have no idea why the questioner might want to do this, I'm afraid.
Since he's normally fairly bright, I presume he had a good reason for
asking.)

The following code illustrates the point, I think (but don't use it as a
va_arg tutorial!, as it kinda assumes there are at least six args after the
named arg):

#include <stdio.h>
#include <stdarg.h>

int foo(int i, ...)
{
va_list ap = {0};
va_list aq = {0};
int sum = i;

va_start(ap, i);
sum += va_arg(ap, int);
sum += va_arg(ap, int);
va_start(aq, i);
sum += va_arg(ap, int);
sum += va_arg(ap, int);
sum += va_arg(aq, int);
sum += va_arg(aq, int);
sum += va_arg(ap, int);
sum += va_arg(aq, int);
sum += va_arg(ap, int);
sum += va_arg(aq, int);
va_end(ap);
sum += va_arg(aq, int);
sum += va_arg(aq, int);
va_end(aq);
return sum;
}

int main(void)
{
printf("%d\n", foo(6, 5, 4, 3, 2, 1, 0));
return 0;
}

Having read through the relevant section of C99, I could find no
standard-based reason why this interleaving should not work (and, indeed,
it does work on the single compiler I tested the code with).

Did I miss something, or am I right in thinking this is a legal,
well-defined technique?
 
J

Jason

There is this to note:

[draft 99]

I7.15.1.4

clause 3.

"...va_start shall not be invoked again for the same ap [ va_list type ]
without an intervening invocation of va_end for the same ap."

Given common compiler implementations it's not surprising that it works
though.
 
R

Richard Heathfield

Jason said:
There is this to note:

[draft 99]

I7.15.1.4

clause 3.

"...va_start shall not be invoked again for the same ap [ va_list type ]
without an intervening invocation of va_end for the same ap."

Given common compiler implementations it's not surprising that it works
though.

It's a different ap.
 
R

Richard Heathfield

"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

And that's the only suggestion I would have regarding your sample
code: instead of calling va_start twice, why not use va_copy ?

Perhaps because he doesn't have a C99 compiler. :)
 
D

Dan Pop

In said:
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:



Perhaps because he doesn't have a C99 compiler. :)

A brilliant illustration of my point: far too many people no longer have
a clear idea about what is a C feature and what is a C99 feature.

Dan
 
I

Ivan Vecerina

| In <[email protected]>
|
| >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
| >
| ><snip>
| >>
| >> And that's the only suggestion I would have regarding your sample
| >> code: instead of calling va_start twice, why not use va_copy ?
| >
| >Perhaps because he doesn't have a C99 compiler. :)
|
| A brilliant illustration of my point: far too many people no longer have
| a clear idea about what is a C feature and what is a C99 feature.

NB: Richard mentioned the C99 standard in his original post,
so this is why I based my reply on this.

This said, I agree with your point.

IMHO, C99 and C90 deserve separate NGs nearly as much as C90 and C++98 do
... Maybe, maybe not ;)


Kind regards,
Ivan
 
D

Dan Pop

In said:
| In <[email protected]>
|
| >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
| >
| ><snip>
| >>
| >> And that's the only suggestion I would have regarding your sample
| >> code: instead of calling va_start twice, why not use va_copy ?
| >
| >Perhaps because he doesn't have a C99 compiler. :)
|
| A brilliant illustration of my point: far too many people no longer have
| a clear idea about what is a C feature and what is a C99 feature.

NB: Richard mentioned the C99 standard in his original post,
so this is why I based my reply on this.

Another (related) point of mine: people read the C99 standard and
expect their C89 implementations to behave accordingly. Which is sheer
foolishness.
This said, I agree with your point.

IMHO, C99 and C90 deserve separate NGs nearly as much as C90 and C++98 do
... Maybe, maybe not ;)

C99 already has a group. It's called comp.std.c. As long as
practically nobody writes C99 code (using the C99 extensions supported
by one C89 implementation or another doesn't count), there is little need
for a newsgroup dedicated to C99 programming.

Once people start using C99 implementations on a significant basis, c.l.c
will naturally "migrate" towards C99, the same way it happened with c.s.c
once the focus of the standardisation effort has moved from C89 to C9x.

The current foolishness in comp.lang.c is practically due to the fact that
an electronic copy of C99 can be cheaply obtained (and its last public
draft is still available for free), which was never the case for C89/C90
(whose electronic copy was both expensive and of poor quality: it
contained a raw scan of standard's pages).

Dan
 
D

Dan Pop

In said:
No, it's relatively low-gradient foolishness. C99 has done very little to
change the parts of C that are already defined by C90. Some, sure, but not
much.

It doesn't matter how much: the text you're actually reading might be one
of those few places where C99 changes the C89 specification. Do you like
gambling on programming issues?

Furthermore, it is quite common for C89 implementations to provide C99
features as extensions, but with different semantics. E.g. snprintf on
Solaris or inline and VLAs on gcc.

Dan
 
R

Richard Heathfield

Dan said:
In <[email protected]> Richard Heathfield


It doesn't matter how much: the text you're actually reading might be one
of those few places where C99 changes the C89 specification. Do you like
gambling on programming issues?

No. I'd far rather use the C89 standard when writing C89 code.
Unfortunately, I don't have a copy of the C89 standard, although I do have
a draft, of course. Given the choice between gambling on a draft, and
gambling on an authoritative standard text that has been revised, I'll take
the latter, and combine it with the excellent group knowledge of
comp.lang.c in an attempt to arrive at a low-risk strategy. That, in fact,
was precisely what I was trying to do here.
Furthermore, it is quite common for C89 implementations to provide C99
features as extensions, but with different semantics. E.g. snprintf on
Solaris or inline and VLAs on gcc.

What about interleaved variable argument processing? Does the published C89
standard have anything to say on the matter?
 
D

Dan Pop

In said:
No. I'd far rather use the C89 standard when writing C89 code.
Unfortunately, I don't have a copy of the C89 standard, although I do have
a draft, of course. Given the choice between gambling on a draft, and
gambling on an authoritative standard text that has been revised, I'll take
the latter, and combine it with the excellent group knowledge of
comp.lang.c in an attempt to arrive at a low-risk strategy. That, in fact,
was precisely what I was trying to do here.

Bad choice. The C89 draft is much closer to C89 than C99.
Unsurprisingly. And most of the differences between the draft and C89
are obvious to the competent C programmer (CLK_TCK instead of
CLOCKS_PER_SEC, the wrong argument type for %o and %x in printf formats).
What about interleaved variable argument processing? Does the published C89
standard have anything to say on the matter?

Any good reason to expect the text to be different from the draft?
Having access to both, I can confirm that the <stdarg.h> specification
is the same in both documents.

Dan
 
R

Richard Heathfield

Dan Pop wrote:


Having access to both, I can confirm that the <stdarg.h> specification
is the same in both documents.

There! That wasn't so hard, was it? Thanks for the confirmation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top