This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: va_list question
- From: "Bob Boz" <gcc_compiler at yahoo dot ca>
- To: "Andreas Schwab" <schwab at suse dot de>
- Cc: <gcc at gcc dot gnu dot org>
- Date: Wed, 22 May 2002 16:50:25 -0400
- Subject: RE: va_list question
> -----Original Message-----
> From: Andreas Schwab [mailto:schwab@suse.de]
> Sent: Tuesday, May 21, 2002 3:00 PM
> To: Bob Boz
> Cc: gcc@gcc.gnu.org
> Subject: Re: va_list question
>
>
> "Bob Boz" <gcc_compiler@yahoo.ca> writes:
>
> |> First off, I hope this isn't off topic here.
> |> Is the code below supposed to work in general? I mean regardless of the
> |> compiler/platform (although the compiler used is gcc):
> |>
> |> void f1 (const char *format, ...)
> |> {
> |> int i=0;
> |> va_list args;
> |> va_start (args, format);
> |> f2 (format, (va_list *)args);
> |> i = va_arg (args, int);
> |> va_end (args);
> |> }
> |>
> |> void f2 (const char *format, va_list * arg)
> |> {
> |>
> |> int j = va_arg (*arg, int);
> |>
> |> }
> |>
> |> My main point of worry is type casting 'arg' to 'va_list *'
> and then calling
> |> *arg inside f2.
> |> Specially that in gcc for ppc (now I can talk about compiler/platform)
> |> va_list is an array.
>
> The C standard says in 7.15[#3]:
>
> The object ap may be passed as an argument to another function; if
> that function invokes the va_arg macro with parameter ap, the value of
> ap in the calling function is indeterminate and shall be passed to the
> va_end macro prior to any further reference to ap.212)
>
> Footnote 212:
> It is permitted to create a pointer to a va_list and pass that pointer
> to another function, in which case the original function may make
> further use of the original list after the other function returns.
>
>
> |> Using gcc.2.95.3 the above code crashes. However, when I change it to :
> |>
> |> void f1 (const char *format, ...)
> |> {
> |> int i=0;
> |> va_list args;
> |> va_start (args, format);
> |> f2 (format, args); <======
> |> i = va_arg (args, int);
> |> va_end (args);
> |> }
> |>
> |> void f2 (const char *format, va_list arg)
> |> {
> |> va_list ap;
> |> __va_copy (ap, arg);
> |>
> |> int j = va_arg (ap, int);
> |>
> |> }
>
> 7.15.3[#2]:
>
> The va_end macro facilitates a normal return from the function whose
> variable argument list was referred to by the expansion of the
> va_start macro, or the function containing the expansion of the
> va_copy macro, that initialized the va_list ap. The va_end macro may
> modify ap so that it is no longer usable (without being reinitialized
> by the va_start or va_copy macro). If there is no corresponding
> invocation of the va_start or va_copy macro, or if the va_end macro is
> not invoked before the return, the behavior is undefined.
>
> In other words, none of your examples is supported by the C standard.
>
> Andreas.
>
How would you then do the above in "standard C"? Basic idea is to divide
processing of optional arguments between f1 and f2.
Thanks,
-B