Skip site navigation (1)Skip section navigation (2)
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>