Jerry Coffin posted:
Yup -- and unless you have a really good reason to do otherwise, you use
signed.
Convince me. Everything so far has persuaded me to use "unsigned".
Benefits:
(1) No UB upon overflow.
(2) 16-Bit type can be used instead of 32-Bit (for storing 40000).
(3) More efficient on machines other than 2's complement.
Given the remainder of the rules, I thought that would be pretty
obvious to anybody.
Rules? Please clarify what rules you are referring to.
Only because your's is a mess.
Convince me. Right now, it just looks like your preaching religion (which
would explain why your arguments can be irrational, and even downright
wrong).
Yes, you've already made it clear that you get most of it backwards.
There's no real need to reiterate the point.
Worldplay. Congratulations. Care to make a real argument?
Persuade me to use signed integer types when storing positive numbers; I'll
acquiesce to your request as soon as I'm convinced.
Yes, you've already made it clear that you use it in many situations to
which it's poorly suited at best. Again, no need to reiterate the
obvious.
Persuade me that it's poorly suited, because right now, it seems perfectly
logical to me to use an unsigned integer type to store a positive number.
Awareness of the rules doesn't change the fact that the code is fragile.
The code is not "fragile". That's a subjective observation, one which is
compounded by an air of incompetency.
Forcing everybody who reads your code to constantly think about a set of
lengthy, rather complex set of rules -- e.g. in section 6.3.1.1 of the
C99 standard, occupy a full page (your shorter set of rules omitted
several possibilities, such as enums). Then we have to deal with the
"usual arithmetic conversions", another page+ set of rules.
Would you like me to dumb-down my language too? Should I say "basic"
instead of "fundamental", "imprecise multiple meanings" instead of
"ambiguous"?
When I speak to young children, I'll dumb-down my language.
When I program for incompetent programmers, I'll dumb-down my code --
thankfully though, I've no intention to do so in the near future.
Even knowing all of that, you're stuck with two facts: first of all, you
need to use signed integers part of the time.
Yes, when storing negative numbers, or interfacing with 3rd party code
which uses signed integers where unsigned integers would be more suited.
Second the rules of the language are oriented toward producing signed
types as the result of a promotion.
Yes, we must cast to overcome this. Take the following code for example:
unsigned short a = 65535, b = 65535;
unsigned c = a * b;
Even if an "unsigned int" can hold the value 4294836225, this snippet can
invoke undefined behaviour because a "signed int" might be 17-Bit, and thus
"unsigned short" would be promoted to "signed int", the two figures would
be multiplied, overflow, and invoke UB. We must keep our whits about us
with regard to integer promotion:
unsigned c = (unsigned)a * b;
Hiding under the bed and using signed integer types all the time won't make
it go away.
Both of these result in combining signed and unsigned. The result is
code that's diffcult to read or understand, and can give strange
results.
Not if coded proficiently.
We all know that subtracting an unsigned from another unsigned can well
give a negative result.
In human maths, yes, but not in C++ maths.
That's normal math. OTOH, consider this:
#include <stdio.h>
#include <limits.h>
int main() {
unsigned short a = USHRT_MAX, b = USHRT_MAX;
// other code, perhaps...
if (a * b < 0)
printf("Result is negative.\n");
Again here, we would need:
unsigned)a * b
On a typical current implementation (twos-complement, 16-bit short, 32-
bit int) this will tell you that the result of multiplying two unsigned
numbers is negative!
The beauty of undefined behaviour.
As with all mathematical operations in computer programming, we must beware
of overflow.
The overflow of signed integer types leads to UB, so it may or may not
yield a negative result... it could very well just hang.
That's a whole lot different from normal math -- if
you multiply two signed numbers and get a negative result, that's at
least conveivable, depending on the values, the fact that those values
might not produce a negative number in normal math notwithstanding.
You still have UB if signed types overflow.
OTOH, to many people, the fact that multiplying two unsigned numbers can
produce a negative result seems just plain WRONG! Knowing how it
happened doesn't change the fact that it shouldn't be possible!
I would rather if "unsigned" were the default.