This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
C pre-DR#8: va_list objects
- From: "Joseph S. Myers" <jsm at polyomino dot org dot uk>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 29 Sep 2004 00:28:40 +0000 (UTC)
- Subject: C pre-DR#8: va_list objects
This pre-DR is for the question Jakub raised in
<http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02802.html> of the validity
of using arrays of va_list (which cause an ICE on some platforms; bug
17716) and structures containing va_list. It's clear what the semantics
should be for the use of any lvalue for an object of type va_list, and as
a quality of implementation matter we should accept uses with any such
expression and compile them correctly without ICE, but it isn't clear
whether they are strictly valid (though if not I think that is more likely
an oversight in the standard than a deliberate decision).
Pre-DR: va_list objects
=======================
C99 7.15#3 says:
[#3] The type declared is
va_list
which is an object type suitable for holding information
needed by the macros va_start, va_arg, va_end, and va_copy.
If access to the varying arguments is desired, the called
function shall declare an object (referred to as ap in this
subclause) having type va_list. 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.214)
Does "the called function shall declare an object ... having type
va_list" mean that a variable of this type must be declared in the
function, or simply that the declarations visible there must permit
the construction of a modifiable lvalue expression of type va_list
that refers to an object (such lvalue expression being referred to as
ap). Do some or all of the following cases have undefined behavior?
If so, which? I believe this paragraph should be reworded to avoid
placing restrictions on where the object is declared and allocated.
Instead, it should be said that the ap parameter is a modifiable
lvalue for an object of type va_list, with no further requirements on
its declaration or allocation.
1. Object declared outside the function.
#include <stdarg.h>
va_list ap;
void
f (int a, ...)
{
va_start(ap, a);
// ...
va_end(ap);
}
2. Object declared outside the function but redeclared inside. This
would appear to meet the letter of the standard, though there can
hardly be any difference to implementations from the previous case.
#include <stdarg.h>
va_list ap;
void
f (int a, ...)
{
extern va_list ap;
va_start(ap, a);
// ...
va_end(ap);
}
3. Pointer to va_list passed in.
#include <stdarg.h>
void
f (va_list *app, ...)
{
va_start(*app, app);
// ...
va_end(*app);
}
4. va_list allocated with malloc.
#include <stdarg.h>
#include <stdlib.h>
void
f (int a, ...)
{
va_list *app;
app = malloc(sizeof(va_list));
if (app) {
va_start(*app, a);
// ...
va_end(*app);
}
}
5. Array of va_list.
#include <stdarg.h>
void
f (int a, ...)
{
va_list apa[10];
va_start(apa[4], a);
// ...
va_end(apa[4]);
}
6. Structure containing va_list.
#include <stdarg.h>
void
f (int a, ...)
{
struct { int a; va_list b; } aps;
va_start(aps.b, a);
// ...
va_end(aps.b);
}
--
Joseph S. Myers http://www.srcf.ucam.org/~jsm28/gcc/
http://www.srcf.ucam.org/~jsm28/gcc/#c90status - status of C90 for GCC 4.0
jsm@polyomino.org.uk (personal mail)
jsm28@gcc.gnu.org (Bugzilla assignments and CCs)