stdarg: safe to pass va_list * and have callees va_arg(*args, type)??
Lawrence Kirby
fred@genesis.demon.co.uk
Fri Oct 1 00:00:00 GMT 1999
In article < 877lmgwz3c.fsf@pfaffben.user.msu.edu >
pfaffben@msu.edu "Ben Pfaff" writes:
>slevy@ncsa.uiuc.edu (Stuart Levy) writes:
>
> I'm working with a C program that makes lots of use of stdarg in the
> following way. It *looks* legal to me, and has worked correctly with many
> compilers. But, some recent versions of egcs (something for PPC, and
> egcs 1.0 for x86) seem to generate incorrect code -- at least, they yield
> *some* wildly incorrect values from va_arg() (and many correct values).
>
> I'm seeking advice on whether that should be considered a
> compiler/runtime-system bug, or whether this is really an unsafe construct.
> (If the former, I'll try to make a real test case and submit a bug report.)
>
> Briefly, a stdarg-using routine is passing the *address* of its
> va_list pointer to various functions, expecting them to update it as
> they grab arguments from it, then grabbing more arguments itself, etc.
>
>This is an odd example of synchronicity. I was just wrestling with a
>related, but not identical, issue myself about an hour ago.
>Fortunately, I have a copy of the Standard at hand, with which I was
>able to straighten myself out.
>
>Basically, the Standard says that va_list is an opaque type.
Nevertheless it is an object type.
> There
>are only two things that you're guaranteed to be able to do with it in
>standard C (after you've initialized it with va_start), AFAICT from
>the Standard:
>
> 1. Pass it to va_arg and va_end directly.
> 2. Pass it as an argument to another function.
The standard talks specifically about the "object ap". I interpret this to
mean that any lvalue designating that object is valid.
>In case (2), it says that if the called function calls va_arg, then
>the value of the va_list in the caller is indeterminate and that
>va_end must be called afterward, rather than va_arg.
The problem here probably stems from the fact that va_list may or may not
be an array type so the object in the caller may or may not by updated
by the called function. By passing a pointer to the object you ensure that
the called function does modify the object in the caller.
>The Standard doesn't seem to define what you can do with a pointer to
>a va_list, so I think that that would be undefined behavior.
A pointer to a va_list is a pointer to an object so behaves just like
any other pointer to an object. IMO this technique should work.
--
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
More information about the Gcc-help
mailing list