NEVER, EVER, NOT IN A MILLION YEARS use a signed int/char etc, unless you are 200% certain you're doing the right thing (that is, it's for something specific you need it)
You WILL have problems, period.
"Oh it's just a matter of knowing the C spec" then please go ahead as I grab the popcorn.
But... your advice as written is just insane. They are real, and required routinely. You can't just apply this as a "for dummies" rule without essentially ruling out half of the code they'll need to write.
A negative number yes, but not really a memory offset (you shouldn't mix negative numbers and memory offset, really)
But yeah, if you're doing "math" go for it, but it's on rare occasions where you need negative numbers (subtraction yes)
The most common case I remember may be sound samples, where you have signed chars.
For all other cases you would be using floating point or decimal numbers
If I'm trying to avoid mathematical anomalies, floating point is not what I would run to... "Equal" is a matter of degree, you have to be careful with anything near zero and you can't carelessly mix together numbers that are a few orders of magnitude different than each other.
But for most of "math" you would go for floating point. You won't reinvent some fixed point math using integers just because...
Can you explain why you would advocate this? Am I misunderstanding you, or missing something?
I replied to the other comment in this thread with an openbsd vulnerability caused by doing what is being advocated (I did choose openbsd to be funny).
With signed integers, you'll run into the same problem with comparing to n+1 at INT_MAX or n-1 at INT_MIN.
It's just my experience. Don't get too wound up about it ;)
There's your problem: that's like saying cars are more dangerous than motorcycles because your finger can get squeezed by the door.
"There's a reason Java, C# etc. default to signed integer"
Legacy? And in Java/C#, and you usually use ints, not so much chars, shorts, etc and casts are probably more picky
I stand by my point, you should only use signed if you know what you're doing and for a specific use only (like math)
It's far too easy to get things wrong when you add unsigned integers into the mix; ever compare a size_t with a ptrdiff_t? Comes up all the time when you're working with resizable buffers, arrays, etc.
And no, Java did not choose signed by default because of legacy. http://www.gotw.ca/publications/c_family_interview.htm:
"Gosling: For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up."
Unsigned is useful in a handful of situations: when on a 32-bit machine dealing with >2GB of address space; bit twiddling where you don't want any sign extension interference; and hardware / network / file protocols and formats where things are defined as unsigned quantities. But most of the time, it's more trouble than it's worth.
Depends on the case of course, but yes, you'll rarely hit the limits in an int (in a char, all the time)
"It's far too easy to get things wrong when you add unsigned integers"
I disagree, it's very easy to get things wrong when dealing with signed
Why? For example, (x+1) < x is never true on unsigned ints. Now, think x may be a user provided value. See where this is going? Integer overflow exploit
Edit: stupid me, of course x+1 < x can be true on unsigned. But unsigned makes it easier (because you don't need to test for x < 0)
"what unsigned arithmetic is"
This is computing 101, really (well, signed arithmetic as well). Then you have people who don't know what signed or unsigned is developing code. Sure, signed is more natural, but the limits are there, and then you end up with people who don't get why the sum of two positive numbers is a negative one.
Here's something you can try: resize a picture (a pure bitmap), with antialiasing, in a very slow machine (think 300MHz VIA x86). Difficulty: without libraries.
In fairness, I guess a function like this is a good example of why you should put in preconditions, as well as a good demonstration that "not all the world is a VAX" (nor MS C 7, nor GCC version N) :-)
Here's some sample C code tested on a 32-bit Linux system:
int main(int argc, char *argv)
unsigned int val1 = 0xffffffff;
printf("val1 == -1: %d\n", val1 == -1);
val1 == -1: 1
Any decent compiler should warn that such a check is always false, but people don't always pay attention to that stuff....