3 ms·
> E.g. C++ is very unhappy with the mistake they made of representing sizes with unsigned types [1]. 95% of that unhappiness seems to be due to mixed signed/un
by gergo_barany 4y ago
> E.g. C++ is very unhappy with the mistake they made of representing sizes with unsigned types [1].
95% of that unhappiness seems to be due to mixed signed/unsigned expressions with implicit conversions. Java wouldn't be forced to repeat the mistake of making conversions implicit.
The other 5% of the unhappiness is "machine integers are not mathematical integers". But that's the case for signed integers anyway. Overflowing your unsigned integer is almost certainly wrong, but overflowing your signed integer is almost certainly wrong as well.
> not many advantages for a language like Java.
Agreed.
- pron 4y ago> 95% of that unhappiness seems to be due to mixed signed/unsigned expressions with implicit conversions. Java wouldn't be forced to repeat the mistake of making conversions implicit. Yes and no. As Stroustrup's document says, this is an inevitable result of allowing arithmetic on unsigned integers (i.e. subtracting an unsigned int variable with the value 2 from an unsigned variable with the value 1 has the same effect as explicitly mixing it with a signed integer by adding a -2). The only way to avoid that is to add runtime underflow checks to unsigned arithmetic. Once we have user-defined value types, people can choose to do just that, but there seems to be little point in adding it to the core language; the cost/benefit just isn't there. > overflowing your signed integer is almost certainly wrong as well. True yet less likely because most integer values appearing in programs are small, and so underflows are more common than overflows.
- cesarb 4y ago> True yet less likely because most integer values appearing in programs are small, and so underflows are more common than overflows. That's a dangerous argument. The values might be small, until an attacker provides a large one. Your code has to work properly with all possible values, regardless of which ones are more "likely" or "common". In my experience, unsigned makes this simpler, since there are only two cases to consider (zero or positive) instead of four (zero, positive, negative, and INT_MIN); I've expanded on this in a comment here an year ago (https://news.ycombinator.com/item?id=29770689 https://news.ycombinator.com/item?id=29770689).
- pron 4y agoThat's one way of looking at it; another is that the common bugs due to underflow with small numbers themselves create more exploitable vulnerabilities. Anyway, I think your point of view is valid, but it will have to become much closer to a consensus before Java considers changing the status quo and adding unsigned types to the core language.
- gergo_barany 4y ago> As Stroustrup's document says, this is an inevitable result of allowing arithmetic on unsigned integers (i.e. subtracting an unsigned int variable with the value 2 from an unsigned variable with the value 1 has the same effect as explicitly mixing it with a signed integer by adding a -2). This is true for C++. It is a meaningless statement in a language where such mixing is not allowed. The semantics of unsigned modular arithmetic can be defined in its own terms, without dragging signed arithmetic and forced implicit conversions into it. The semantics of "subtracting" (unsigned, modularly) 2 from 1 is UINT_MAX. This may or may not be what the user wanted. The semantics of subtracting signed 2 from a signed variable called `arrayIndex` with the value 1 is -1. This is almost certainly not what the user wanted. Why should the language police one case and not the other? It doesn't know the context.
- pron 4y ago> The semantics of subtracting signed 2 from a signed variable called `arrayIndex` with the value 1 is -1. This is almost certainly not what the user wanted. Why should the language police one case and not the other? It doesn't know the context. Because in many situations it does know the context or figures it out quickly. Unlike the former case, if you compute a size and get a negative result you can tell it's wrong, and most uses would result in an immediate exception. It's much harder to detect a bad unsigned value. You can think of the sign bit as a bad value bit for values that are supposed to be positive. An alternative would be to add runtime checks that throw an exception on underflow, but that's already a much bigger change in the service of a feature that very few use to begin with. Those few who wish to work with unsigned types can do so efficiently in Java with the unsigned methods in Integer and Long that were added in JDK 8 (https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/Integer.html https://docs.oracle.com/en/java/javase/19/docs/api/java.base...). Those relatively rare uses, however, don't merit support in the core language, especially when they're known to bring danger with them. A popular library may choose to return sizes as unsigned values -- like C and C++ did with size_t, something many consider a mistake (although there there are many more valuable uses of unsigned types in C/C++ thanks to bitfields) -- and now unsuspecting users who otherwise have no need for unsigned types, the vast majority of users, are susceptible to a new kind of common bug. It's just not worth it.