Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2006-06-03 13:20:18

Topher Cooper <topher_at_[hidden]> writes:

> 1) Unsigned integer is not just an arbitrary restriction on range but
> an important concept in its own right. Its use clarifies intent. In
> my opinion, for example, it is a common, though minor, programming
> error to use "int" rather than "unsigned int" when you intend to
> express cardinality of something (e.g., the size of an array). The
> only real justification otherwise is to allow such practical "tricks"
> as testing if a decreasing index is less than 0.

I happen to use unsinged ints when I mean nonnegative numbers, but
several people have argued that they're error-prone than signed ints,
with good reason... Oh yeah, we just saw an example of it in the bjam

Also, some constraints just aren't worth expressing in the type

        for (unsigned x = 0; x < 20; ++x)

has no particular value over

        for (int x = 0; x < 20; ++x)

It's hard to argue that it's less obvious that x is nonnegative in the
2nd case. Of course, using size_t instead of int does have some
worthwhile semantic value, but I consider the fact that size_t is
unsigned to be an artifact.

> 2) The extra data type, assuming that the design error of deriving
> unsigned_integer from integer is avoided, would add complexity for
> boost maintainers but virtually none for users.

More to understand. Adds the need to make a decision about which type
to use.

> It is, after all a
> logical extension of the built in types -- it takes the user all of 5
> seconds to understand it, if that.

No. The type, as proposed, has very different behavior than the
builtins at the boundaries. Or should I say "boundary?" An infinite
precision unsigned has only a single boundary, zero, and isn't
modular. And you can't make it behave like the builtins -- what value
would it wrap around to? So it's very different from the builtin
type, and presents a trap for the unwary.

> Good library design is user-centric.


> Developer-centric design is the root of a great deal of evil. Lack
> of development/maintenance resources is, of course, a valid
> argument, but this is a completely different issue than that of the
> evils of unnecessary complexity.

No. Complexity for developers always, ultimately, has a cost to the
users they serve. Complexity should only be shouldered if there are
benefits that dwarf those costs. In this case, there are not.

> 3) Normal use of an unsigned integer type will never "try" to produce
> a negative result -- its not a meaningful concept, so if you play by
> the rules it doesn't happen. You certainly would never try to negate
> a cardinality (how often do you write code that says "If this string
> contains 27 characters then I want another one containing -27
> characters?). Subtraction does have to be done with care, but in
> most cases the issue of subtracting a larger from a smaller doesn't
> come up. Subtraction generally appears, sometimes subtly so, as a
> computation of the size of the complement of a subset within a larger
> set. If you are dealing with where you would want to use unsigned
> integers and you unwittingly do subtract a larger from a smaller
> value -- if your program logic does not protect you from it -- than
> you better have an exception.

Not if it's just an intermediate value. As shown in the bjam example
above, you might just be introducing an error condition/exception
where none was needed.

Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at