This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]