From owner-freebsd-bugs Thu May 17 10: 8:54 2001 Delivered-To: freebsd-bugs@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 5D5D637B424 for ; Thu, 17 May 2001 10:08:50 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id DAA22931; Fri, 18 May 2001 03:08:30 +1000 Date: Fri, 18 May 2001 03:07:06 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Cyrille Artho Cc: bugs@FreeBSD.ORG, Ernst de Haan Subject: Re: Insufficient type casts in stdargs.h In-Reply-To: <3B03C53C.349F9491@silmaril.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org On Thu, 17 May 2001, Cyrille Artho wrote: > Hi, > in FreeBSD 4.3's stdargs.h, the macro va_arg does not contain enough > type casts. As a result, gcc 2.95.3 rejects using va_arg with void* > arguments. > ... > Original source code: > > parameter[n_parameters++] = va_arg(ap, void*); The bug seems to be in your declaration of `ap' (which is not shown here). `ap' must have type va_list (which happens to be `char *' for FreeBSD on i386's). > ------------------------------------------------------------------------- > > Linux little endian systems: > > #define va_arg(AP, TYPE) > \ > (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), > \ > *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))) > > Expanded source code: > parameter[n_parameters++] = ( ap = (__gnuc_va_list) ((char *) ( ap ) + > (((sizeof ( void* ) + sizeof (int) - 1) / sizeof (int)) * sizeof > (int)) ), *(( void* *) (void *) ((char *) ( ap ) - (((sizeof ( > void* ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) ))) ; The cast to `char *' is required here because we want to do pointer arithmetic on `AP' but the type of `AP' is `void *'. The cast to `void *' has no effect here, because __gnuc_va_list happens to be `void *', but casting to __gnu_va_list is required in general. > ------------------------------------------------------------------------- > > FreeBSD: > > #define va_arg(ap, type) \ > (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) > > Expanded source code: > parameter[n_parameters++] = (*( void* *)(( ap ) += (((sizeof( void* > ) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) , ( ap ) - > (((sizeof( void* ) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) > )) > > jlint.cc:141: ANSI C++ forbids using pointer of type `void *' in > arithmetic > jlint.cc:141: ANSI C++ forbids using pointer of type `void *' in > arithmetic There is no pointer of type `void *' in arithmetic here, provided `ap' is declared correctly. The arithmetic is `(ap) += integer' where `ap' should have type `char *'. The expression is a little simpler than in Linux because `ap' has a convenient type. This simplification is possible because is machine-dependent. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message