Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2018 23:14:43 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Eitan Adler <eadler@freebsd.org>, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r335041 - head/lib/libc/stdlib
Message-ID:  <20180613211443.GA57326@stack.nl>
In-Reply-To: <20180613194008.W2003@besplex.bde.org>
References:  <201806130852.w5D8qH9a093758@repo.freebsd.org> <20180613194008.W2003@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Jun 13, 2018 at 08:03:13PM +1000, Bruce Evans wrote:
> On Wed, 13 Jun 2018, Eitan Adler wrote:

> > Log:
> >  libc: remove explicit cast NULL in atoi

> >  There isn't any reason to cast NULL so just remove it. Noticed when
> >  cleaning up top.

> There are many reasons to cast NULL for all members of the ato*() family:
> - it is required if no prototype is in scope
> - C99 specifies ato*() in terms of strtol*() and uses the cast to NULL,
>    probably because this is simplest.  Omitting the cast is just wrong
>    if no prototype is in scope.  Writing the explicit cast is simpler than
>    writing caveats that the stated equivalence is only valid if a prototype
>    is in scope.
> - POSIX specifies ato*() in terms of strtol*() and uses the cast to NULL,
>    exactly as in C99, probably because it defers to the C standard and
>    doesn't and doesn't risk breaking it by changing its wording except when
>    extending it.

These reasons can be summarized to a single reason: the cast is required
if no prototype is in scope.

I think it is unwise to call any function without a prototype in scope,
since this runs a risk of undefined behaviour if you get the types
wrong.

For the code in libc, we ensure a prototype is in scope and no cast is
required. For the code in the man page, I doubt we should allow for
programmers that play tricks by declaring system functions manually
using K&R-style declarations or (even worse) call functions without
declaring them at all.

Note that NULL may still need a cast when passed to a function with
variable number of parameters. Ideally these types are also checked
using attributes.

> FreeBSD used to do the same here, and should do the same here and
> elsewhere by copying better wording from POSIX whenever possible.

For some reason, the FreeBSD text does not have the exception about
error handling. This exception permits an implementation like musl's
which calculates using int and hard-codes base 10, even if the compiler
documents a cast from long to int as truncating bits. I don't think we
should take advantage of this, though, since making atoi() faster than
strtol() may encourage people to use atoi().

-- 
Jilles Tjoelker



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