"Never use a signed type for a number that can never be negative"
One of my pet peeves is developers using int (instead of unsigned ints) for primary keys in database tables.
I'm pretty sure that it's just because "int" is one word and "unsigned int" is two, plus more than twice the characters. I suspect if "int" defaulted to "unsigned int" and you'd have to specify signed ints explicitly, the taboo would be reversed.
Never underestimate the power of trivial inconveniences.
for (int i = x.size() - 1; i >= 0; i--) ...
for (int i = 0; i < x.size() - 1; i++) if (x[i] < x[i+1]) ...
Both will blow up badly with unsigned ints.(Well, to be fair, both will blow up with signed ints if x.size() is greater than 2G, so it's a matter of expectations.)
// count up
std::size_t i = 0;
while (i != 10)
{
std::cout << i << "\n";
++i;
}
// count down
std::size_t i = 10;
while (i != 0)
{
--i;
std::cout << i << "\n";
}
After initialization a for statement repeats "test; body; advance", this is ideal for counting up loops, but what we need for counting down loops is "test; advance; body". Since C/C++ do not provide the latter as a primitive you have to use a while loop as shown above. Using a signed integer to shoehorn a counting down loop into a for statement at the cost of 1/2 your range is a hack IMO. Note that when working with iterators you have to resort to a while statement as iterating past begin is UB.That yields compiler warnings for signed vs unsigned then, no?
In this case, it makes absolutely no difference at all. It could be argued that writing unsigned int would make the code slightly harder to read. That said, I like to use stdint.h and unint32_t would, I think, not have any drawbacks.
> there is lot of code out there with interfaces expecting signed ints even though they should using uint
That's not a good reason to not use unsigned integers, it's a zero-overhead cast from unsigned to signed (at the risk of overflowing into the negative).
Using uint limits the optimizer...
There's example code on the CERT secure coding guidelines here (look under 'Substraction'):
https://www.securecoding.cert.org/confluence/display/seccode...
Writing safe code to calculate the absolute difference between two unsigned integers is much less hairy: max(x,y) - min(y,x).
Really, working directly in fixed-precision arithmetic is absurd. In order to be able to rely on its correctness with any degree of certainty, you need to very carefully track each operation and its bounds, at which point you may as well have just used arbitrary-precision types, explicitly encoded your constraints, and had the compiler optimize things down to scalar types when possible, warning when not.
"SQL only specifies the integer types integer (or int), smallint, and bigint." http://www.postgresql.org/docs/9.3/static/datatype-numeric.h...
1) If you don't need negative numbers, use unsigned integers.
2) If you don't need the extra positive range of unsigned integers (or defined wrapping), use signed.
You advocate (1), but C is generally based on (2), with the default int being signed, and many standard functions using plain int.
Having a negative pkey space is actually useful. In LSMB we reserve all negative id's for test cases, which are guaranteed to roll back. This has a number of advantages including the ability to run a full test run on a production system without any possibility of leaving traces in the db.
[0] though several do support UUIDs, which are essentially unsigned 128-bit ints, and which (with a well-selected generation mechanism) are better as server-assigned surrogate keys than sequential integers, signed or unsigned, anyway.
if (index < 0) { /* error */ }
I die a little inside.Seems like a pretty ignorant pet peeve considering that's the only option for every database that doesn't auto-corrupt data.