Expert C Programming

(Jeff_L) #1

}


The defined variable TOTAL_ELEMENTS has type unsigned int (because the return type


of sizeof is "unsigned"). The test is comparing a signed int with an unsigned int quantity. So
d is promoted to unsigned int. Interpreting -1 as an unsigned int yields a big positive
number, making the clause false. This bug occurs under ANSI C, and under K&R C if


sizeof() had an unsigned return type in a given implementation. It can be fixed by


putting an int cast immediately before the TOTAL_ELEMENTS:


if (d <= (int) TOTAL_ELEMENTS - 2)


Handy Heuristic


Advice on Unsigned Types


Avoid unnecessary complexity by minimizing your use of unsigned types. Specifically,
don't use an unsigned type to represent a quantity just because it will never be negative
(e.g., "age" or "national_debt").


Use a signed type like int and you won't have to worry about boundary cases in the


detailed rules for promoting mixed types.


Only use unsigned types for bitfields or binary masks. Use casts in expressions, to make all
the operands signed or unsigned, so the compiler does not have to choose the result type.


If this sounds a little tricky or surprising, it is! Work through the example using the rules on the
previous page.


Finally, just so that we don't see this code appear as a bad example in a future edition of The Elements
of Programming Style [7], we'd better explain that we used


[7] The Elements of Programming Style, Kernighan (yes, that Kernighan) and Plauger, New York, McGraw-


Hill, 1978. A thundering good read, credible plot, great little book—buy it, read it, live it!


#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))


instead of


#define TOTAL_ELEMENTS (sizeof(array) / sizeof(int))

Free download pdf