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
source
(http://news.gmane.org/find-root.php?message_id=%3c3212b1a80605210414u63627d00nfd0ad52f2f6c1f5%40mail.gmail.com%3e)

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

        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.

Yes.

> 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
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk