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]

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)


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