Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Apr 2004 08:49:41 -0700
From:      "David O'Brien" <obrien@freebsd.org>
To:        ia64@freebsd.org
Subject:   Re: va_list q
Message-ID:  <20040422154941.GD78422@dragon.nuxi.com>
In-Reply-To: <20040422044543.GA78422@dragon.nuxi.com>
References:  <20040421155127.GS57650@netch.kiev.ua> <20040421165307.GB832@ns1.xcllnt.net> <20040422044543.GA78422@dragon.nuxi.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Apr 21, 2004 at 09:45:43PM -0700, David O'Brien wrote:
> On Wed, Apr 21, 2004 at 09:53:07AM -0700, Marcel Moolenaar wrote:
> > On Wed, Apr 21, 2004 at 06:51:27PM +0300, Valentin Nechayev wrote:
> > The use of va_arg(args, va_list) works on ia64 (FreeBSD, HP-UX and Linux).
> > Given the limited context, I can only suggest that you try to create a
> > temporary variable of type va_list and change the offending line to:
> > 
> > 	va_list tmpvalist = va_arg(args, va_list);
> > 	n = vslprintf(buf, buflen + 1, f, tmpvalist);
> ..snip..
> > #include <stdarg.h>
> > #include <stdio.h>
> > 
> > int
> > vf2(int count, va_list ap)
> 
> 
> Still wrong:
> 
>     sledge$ cc arg.c 
>     sledge$ ./a.out 
>     Segmentation fault (core dumped)
> 
> your test program isn't ISO-C compliant.

The details:

This code breaks because it is not ISO-C compliant.  Marcel's suggestion
also isn't ISO-C compliant.  One must use va_copy() just like one needs
to use strcpy() to get a unique copy of a C string.  There are two
platforms to date where GCC takes "advantage" of the ISO-C99 standard and
impliments stdargs in a way that depends on compliant code.

Note that the "#ifdef __powerpc__" code is ISO-C compliant and should
work on all platforms.

1. Adhere to ISO C specification for stdargs:

    Do not copy ap directly:
    void foo (va_list ap) {
        va_list tap = ap;
        /* use tap */
    }

    Correct usage:
    #include <stdargs.h>
    void foo (va_list ap) {
        va_list tap;
        va_copy (tap, ap);
        /* use tap */
    }

    GCCs ap is a pointer for AMD64.  &ap does not do what you may expect.

    Review ISO C99 standard, Section 7.15.

-- 
-- David  (obrien@FreeBSD.org)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040422154941.GD78422>