This is a record of changes to the code since its publication in Dr. Dobb's Journal #233 (August 1995) Volume 20 Issue 8.
CANONIZE
macro
#define CANONIZE(Array,NumInts,NumElem) \ (Array)[NumInts - 1] &= (bit)~0 >> (BITS_SZ - ((NumElem % BITS_SZ) \ ? (NumElem % BITS_SZ) \ : BITS_SZ));
ba_count()
Replaced if (8 == BITS_SZ)
with
if (bitcount[(sizeof bitcount / sizeof bitcount[0]) - 1] == BITS_SZ)
, i.e. replaced the `magic number' 8
with a computed constant.
The last element of the array represents the count of bits that are 1
in the largest integer that can be encoded by type `bit
'. That integer will have all of its bits 1
. Therefore, the count of 1
s in that integer will be how many bits are in the type `bit
'. The sizeof
expression evaluates to the last element of the array.
ba_value()
Replaced return(arr[elem / BITS_SZ] & (1 << (elem % BITS_SZ)));
with return( (arr[elem / BITS_SZ] & (1 << (elem % BITS_SZ))) ?TRUE: FALSE );
.
This is on the advice of Geir Horn <Geir.Horn@si.sintef.no>. The change does not affect ANSI C implementations but might have an impact on some other compilers.
NELEM
macro((N + BITS_SZ - 1)/BITS_SZ)
(In C, division of positive integers truncates.)ba_count()
Replacedfor (count = 0L; i < size; i++)
with
for (count = 0L, i = 0; i < size; i++)
Otherwise the variable i
is uninitialized in the second
loop. My thanks to Dan Pop <danpop@mail.cern.ch> for telling me that
the gcc compiler needs a -O switch to enable all the
error checking of -Wall. Curiously, the Solaris distribution of
lint didn't catch the error.
malloc()
should properly be defined in
<stdlib.h>
not <malloc.h>
.
Furthermore, although the article referred to <limits.h>
it was not included in the code. The cast of malloc
in
ba_b2str()
is unnecessary.
BITS_SZ
definitionIt occurred to me today that (sizeof bit) *
(CHAR_BIT)
would be exactly the number of bits in each
variable of bit
type. I don't know why I didn't think of it
before -- it seems obvious. If the changes were made then the code would
be independent of the type used (as long as it is one of the unsigned
integral types).
#define BITS_SZ (CHAR_BIT)
(sizeof bit) * (CHAR_BIT)
is more versatile.elem_t BITS_SZ = 0
BITS_SZ
should be static
(because:
(a) it would be like the #ifdef
version; and (b) the symbol
should not be external anyway.)calloc()
and malloc()
are
unnecessary and set a bad example.return (arr); /* etc. */
return
look like a function when
it is not required. About the most minor matter of style there can
be.