Date: Sun, 03 Feb 2002 20:56:53 -0800 From: Peter Wemm <peter@wemm.org> To: Bruce Evans <bde@zeta.org.au> Cc: Juha Juntunen <estabur@hotmail.com>, arch@FreeBSD.ORG Subject: Re: __P macro question Message-ID: <20020204045653.CCDEA3809@overcee.wemm.org> In-Reply-To: <20020202012011.U3304-100000@gamplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Bruce Evans wrote: > On Fri, 1 Feb 2002, Juha Juntunen wrote: > > > >>>static int sendfile __P((struct printer *pp, int type, char *file, > > >>> int format)); > > >>> > > >>>for a procedure declaration of: > > >>> static int > > >>> sendfile(pp, type, file, format) > > >>> struct printer *pp; > > >>> int type; > > >>> char *file; > > >>> char format; > > >>> { > > >> > > >>That's *EXCATLY* why I'm converting the old, but still legal in c89, > > >>style to new style. You get warnings that you didn't get before. > > > > > >The compiler is broken, if it accepts the second when the > > >first prototype is in scope. > > > > > >It's a broken compiler, period. > > > > How is the compiler broken, question mark. > > > > Are you perhaps objecting to the type of the last parameter > > ("int format" vs "char format")? Please see Ansi Classic, chapter > > "3.5.4.3 Function declarators (including prototypes)", in particular > > page 69 lines 19-22. In C99, 6.7.5.3 paragraph #11 seems to apply > > similarly. > > Right. I don't trust anyone who is not familiar with this point to > globally remove __P. > > People removing __P should also be familiar with the gcc conterpoint: > > void foo(char); /* Wrong; should be "void foo(int);". */ > void foo(c) char c; {} > > gives undefined behaviour in Standard C, but gcc defines its behaviour > to be do-what-naive-programmer-expects. This is only safe provided the > wrong prototype for foo() is always in scope before foo() is called; > otherwise foo() is sometimes passed an int and sometimes a char, but > foo() expects to be passed either an int or a char depending on whether > the wrong prototype is in scope for the function body. There are also variations depending on CPU ABI as well. For the i386 ABI that we use on FreeBSD, a "char" argument (prototyped even) is passed as an "int", always, period. On the Alpha, integral types are passed as 64 bit types. Same on the ia64. I am not sure about sparc64, ppc. Ironically, this means that most of the 'long/int' stuff that upsets people for argument passing on all the 64 bit platforms that I know about, is actually [mostly] harmless. printf("%d %d", (long)i, (long)j) works fine on alpha and ia64, for example.. even though long = 64 bit and int = 32 bit. The bottom line is that using -Wmissing-prototypes and having it compile cleanly is the only safe option that we have. This is doubly important on ansi-fied code as we pass over it. Cheers, -Peter -- Peter Wemm - peter@FreeBSD.org; peter@yahoo-inc.com; peter@netplex.com.au "All of this is for nothing if we don't go to the stars" - JMS/B5 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020204045653.CCDEA3809>