varargs function, is this legal?

D

David G

void myfunc(char *format, int param1, ...)
{
va_list argp;

va_start(argp, format);
#if CONDITION
some code involving param1
#endif
some code that uses format and argp
va_end(argp);
}

The obvious thing being that the function in question, under certain
build configurations, needs to snoop the first varargs parameter.
I've seen the comment made on various pages about varagrs that the
second parameter to va_start is the last named parameter of the
function, but is this a hard requirement?

The reason I'm curious is that when heavily optimized, when CONDITION
evaluates false, MS VC 2005's compiler will optimize out the
evaluation of param1 since it's not actually used in the function.
This in turn causes all sorts of hell because the parmeters fetched
via argp don't line up properly.

Compiler bug, or are we breaking the law?
 
K

Keith Thompson

David G said:
void myfunc(char *format, int param1, ...)
{
va_list argp;

va_start(argp, format);
#if CONDITION
some code involving param1
#endif
some code that uses format and argp
va_end(argp);
}

The obvious thing being that the function in question, under certain
build configurations, needs to snoop the first varargs parameter.
I've seen the comment made on various pages about varagrs that the
second parameter to va_start is the last named parameter of the
function, but is this a hard requirement?

Yes, it's a hard requirement (well, "hard" in the sense that if you
violate it then your program's behavior is undefined).

See C99 7.15.1.4:

#include <stdarg.h>
void va_start(va_list ap, parmN);
...

The parameter parmN is the identifier of the rightmost parameter
in the variable parameter list in the function definition (the one
just before the , ...).

Since the standard doesn't define the behavior of va_start() when its
second argument is something other than the rightmost parameter, the
behavior is undefined; all bets are off.

For your function, va_start(argp, param1) is the only valid call.

[...]
 
E

Eric Sosman

David said:
void myfunc(char *format, int param1, ...)
{
va_list argp;

va_start(argp, format);

BZZZT! Thank you for playing; you win the all-expenses
paid "January in Jutland" trip, including free tickets to the
Frostbite Festival, where you'll get to meet the Ice Maidens
(and maybe kiss them, if you've brought enough ChapStick).
#if CONDITION
some code involving param1
#endif
some code that uses format and argp
va_end(argp);
}

The obvious thing being that the function in question, under certain
build configurations, needs to snoop the first varargs parameter.
I've seen the comment made on various pages about varagrs that the
second parameter to va_start is the last named parameter of the
function, but is this a hard requirement?

Yes: 7.15.1.4p4.
The reason I'm curious is that when heavily optimized, when CONDITION
evaluates false, MS VC 2005's compiler will optimize out the
evaluation of param1 since it's not actually used in the function.
This in turn causes all sorts of hell because the parmeters fetched
via argp don't line up properly.

Compiler bug, or are we breaking the law?

With va_start(argp, format) you are breaking the law.
If there's some other skulduggery going on, please post
actual complete code for further discussion.
 
P

Peter Nilsson

void myfunc(char *format, int param1, ...)
{
va_list argp;

va_start(argp, format);
#if CONDITION
some code involving param1
#endif
some code that uses format and argp
va_end(argp);
}

void myfunc(char *format, ...)
{
va_list argp;

#if CONDITION
{
va_list argp2;
int param1;
va_start(argp2, format);
param1 = va_arg(argp2, int);
va_end(argp2);

some code involving param1
}
#endif

va_start(argp, format);
some code that uses format and argp
va_end(argp);
}
 
D

David G

     BZZZT!  Thank you for playing; you win the all-expenses
paid "January in Jutland" trip, including free tickets to the
Frostbite Festival, where you'll get to meet the Ice Maidens
(and maybe kiss them, if you've brought enough ChapStick).

I'll tell you this to your face. Your C skills are clearly excellent,
however I'm glad I don't interact with you on a day to day basis,
because your inter-personal skills are extremely lacking. You'd do
well to think in terms of phrasing it more like this:

"The code you've cited is extremely likely to fail, since the C
standard requires (*) that the second parameter to va_start be the
last named parameter of the enclosing function."

That gets the message home without being so abrasive. ;)

(*) As noted by Richard Heathfield, the phrasing in the standard could
be improved upon by altering the word "is" to say "shall be". ;)
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top