Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Sep 2014 15:53:24 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Garrett Cooper <yaneurabeya@gmail.com>
Cc:        Julio Merino <jmmv@freebsd.org>, "rpaulo@freebsd.org" <rpaulo@freebsd.org>, freebsd-arch@freebsd.org
Subject:   Re: [RFC] Add __arraycount from NetBSD to sys/cdefs.h
Message-ID:  <20140904151838.X1355@besplex.bde.org>
In-Reply-To: <CAGHfRMBMPra5YXDn0e83dpVxwnarg3DL8o31xr7DhWv%2BVXskTg@mail.gmail.com>
References:  <CAGHfRMBMPra5YXDn0e83dpVxwnarg3DL8o31xr7DhWv%2BVXskTg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 3 Sep 2014, Garrett Cooper wrote:

> Hi all,
>    In order to ease porting code and reduce divergence with NetBSD
> when importing code (a large chunk of which for me are tests), I would
> like to move nitems to sys/cdefs.h and alias __arraycount to nitems.
>    Here's the __arraycount #define in lib/libnetbsd/sys/cdefs.h:
>
> 44 /*
> 45  * Return the number of elements in a statically-allocated array,
> 46  * __x.
> 47  */
> 48 #define __arraycount(__x)       (sizeof(__x) / sizeof(__x[0]))
>
>    Here's the nitems #define in sys/sys/param.h:
>
> 277 #define nitems(x)       (sizeof((x)) / sizeof((x)[0]))

The NetBSD version is less namespace-polluting.  The underscores in the
name of its __x parameter are bogus (plain x would be in the macro's
namespace).

The version in the patch is vastly more namespace-polluting.  It adds
nitems() to <sys/cdefs.h> and thus defeats the careful underscoring
of all (?) other public names there.

nitems() in <sys/param.h> was bad enough.  It is of course not documented
in any man page.  <sys/param.h> has lots of historical pollution.  It is
still used a lot.  Adding nitems() to it broke any application that uses
this name for almost anything except possibly as a plain identifier
(nitems followed by a left parentheses gives the macro, but nitems not
followed by a left parenthese might not be broken).  Since nitems is a
very reasonable variable name, its pollution is more likely to break
applications than most.

I don't like depending on either nitems() or __arraycount() being in
a system header.  Any use of these is unportable at best.  Most uses
of reserved identifiers are undefined (C99 7.1.3p2).  Use of
__arraycount is no exception, since it is of course not documented in
any man page.  In practice, the undefined behaviour is usually just
unportability.

The only portable way to use these macros is to write your own version
and spell it without leading underscores.  Even this is not portable,
due to bugs like the undocumented nitems() in <sys/param.h>.  Use of
<sys/param.h> is also unportable, but it should be possible to know
what is in it by reading its documentation and not necessary to reread
it often to check for new pollution in it.

I usually spell my version of this macro it more like arraycount() than
nitems().  nitems() is too generic even for local use.  arraycount() is
too verbose without being completely precise about what is being counted.

Bruce



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