Live data from Hacker News

Unsigned sizes: A five year mistake

c3-lang.org

121–130 of 153 posts

Re: Unsigned sizes: A five year mistake

#121
post #88

Earlier quoted context omitted.

In C your compiler can help you with conversions and if not, please use a better one. In this regard, C is a very pragmatic language, and hence for actual work it is a more "serious" programming language than programming languages which are based on some idealistic theory that pedantic typing will fix all your problems, but actually keep you from doing your job.

Sentence 1: The C compiler can help you catch implicit conversion errors. Sentence 2: Catching implicit conversion errors is idealistic, pedantic, and prevents you from doing your job. Great stuff. 10/10. No notes.

The point is that you can get the warnings without having to deal with a strict type system all the time.

Re: Unsigned sizes: A five year mistake

#122
post #87

Earlier quoted context omitted.

It is interesting that you find unsigned integers more intuitive. My experience (also with students, but also analysis of CVE give plenty of evidence) is that the opposite is true: signed integers in C are a model of integers which have a nice mathematical structure which people learn in elementary school. Yes, this breaks down on overflow, but for this you have to reach very high numbers and there is very good tooli…

The fixed-size signed types of C etc are no more the actual integers, and no less modular arithmetic, than the fixed-size unsigned types. They both implement the exact same modular arithmetic for +, -, and *. It's only for other operations (ordering comparisons, or / and % which in turn are defined in C in terms of ordering structure, as in rounding towards zero) where they differ. And in either case, that ordering s…

Singed integers in C do not implement modular arithmetic. You can trust me on this.

Re: Unsigned sizes: A five year mistake

#123
post #78

Bjarne agrees. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p14...

There is a really convincing set of arguments against this idea by Robert Seacord[1]. I used to be in the signed size camp, but I've come around to preferring unsigned as much as possible because it's much easier to reason about. I think there are far more footguns than people realize when it comes to signed integers. [1] https://www.youtube.com/watch?v=82jVpEmAEV4

The only real benefits to unsigned math are that overflow is generally defined as a simple wrap (odometer), and it doubles the range. Relying on that doubled range for bounds is flirting with disaster, though.

The downside is a pervasive, constant footgun every time you are dealing with indices.

Re: Unsigned sizes: A five year mistake

#124

Earlier quoted context omitted.

Modulo arithmetic is taught to American students as clock arithmetic in elementary school as well. Signed integers are better described as truncated 2-adics, which are definitely an advanced topic. It's basically a Greenland/Iceland situation. The complicated, difficult one is given a friendly name to trap naive programmers.

Signed ints are no more and no less truncated 2-adics than unsigned ints. Signed ints and unsigned ints are isomorphic as rings; they are both the ring of integers modulo some 2^n. It is only on other operations (ordering comparisons, or the / and % of C) where they differ, and in neither case do these operations have anything to do with 2-adics.

It's a much more useful correspondence than just an isomorphism. Take your base-2 2-adic integer. Truncate it to whatever bitwidth you want. That's the two's complement representation of that number. Unsigned pops out as a special case, obviously.

I've mostly seen this used by cryptographers to prove results over arbitrary bitwidths, since you can prove it over the p-adics and deal with truncation/division separately.

Re: Unsigned sizes: A five year mistake

#125

Systems programmers love to hate on unsigned integers. Generations have been infected with the Java world model that integers have to be pretend number lines centered on zero. Guess what, you still have boundary conditions to deal with. There are times when you really really need to use the full word range without negative values. This happens more often with low level programming and machines with small word sizes,…

> Systems programmers love to hate on unsigned integers I don't see this hate in Rust. I think this is a big thing in the C-related languages, and that the author has chosen to pretend that's the same for any "systems language" but it is not.

> I don't see this hate in Rust.

Nor it is in C++. Most default flag setup will report implicit conversions on numerical as error in C++

Unsigned / signed is mainly an issue if your language chose to silent implicit conversions.

Which honestly, is terrible design beyond simply signed / unsigned.

Re: Unsigned sizes: A five year mistake

#126
post #121

Earlier quoted context omitted.

Sentence 1: The C compiler can help you catch implicit conversion errors. Sentence 2: Catching implicit conversion errors is idealistic, pedantic, and prevents you from doing your job. Great stuff. 10/10. No notes.

The point is that you can get the warnings without having to deal with a strict type system all the time.

Warnings are just noise, so there's no point in printing them--they will be ignored (maybe not when there is a singular warning, but if warnings are allowed to accumulate beyond some manageable threshold). If a warning is worth printing, it should be treated as an error, and if you treat it as an error, you now are "strict" by definition.

Re: Unsigned sizes: A five year mistake

#127
post #48

Earlier quoted context omitted.

Java doesn't have unsigned as primitive types, because James Gosling did a series of interviews at Sun among "expert" C devs, and all got the C language rules for unsigned arithmetic wrong. Yes I miss them in Java as primitives, however there are utility methods for unsigned arithmetic, that get it right.

The way he conducted those interviews, and the conclusions he drew from them, may have been flawed. Because the situation now is that C has unsigned types and Java mostly has not. And despite all pitfalls especially around mixing signed and unsigned in C, unsigned types are very useful, I'd in fact say that for low-level programming they are essential.

He could've removed implicit signed conversion

Re: Unsigned sizes: A five year mistake

#128
post #122

Earlier quoted context omitted.

The fixed-size signed types of C etc are no more the actual integers, and no less modular arithmetic, than the fixed-size unsigned types. They both implement the exact same modular arithmetic for +, -, and *. It's only for other operations (ordering comparisons, or / and % which in turn are defined in C in terms of ordering structure, as in rounding towards zero) where they differ. And in either case, that ordering s…

Singed integers in C do not implement modular arithmetic. You can trust me on this.

I'd trust you a lot more if you actually pointed out something wrong with my statement.

Re: Unsigned sizes: A five year mistake

#129
post #3

Earlier quoted context omitted.

Having them available is not the issue, using them for sizes and indices is what causes a lot of tricky bugs.

Why does an unsigned type for sizes or indices fare worse than a signed type? When do I want the -247th element in an array? When do I have a block that is -10 bytes in size?

Let's say you have two indices into an array: a and b. You want to know how much earlier a is than b so you compute b-a, but as b was in fact the earlier one you get a negative number.

You can deal with this by casting before doing the subtraction, or you can deal with it by storing the indices as signed integers at all times. The latter is more ergonomic at the cost of wasted capacity.

Re: Unsigned sizes: A five year mistake

#130
post #31

Earlier quoted context omitted.

Not sure what change in the C standard you mean. unsingned was always modulo. Otherwise, use -Wsign-conversion.

Nope. It was undefined what happens at unsigned overflows and underflows. Therefore a compiler could choose to implement "unsigned" as either non-negative numbers or as integer residues. The fact that "sizeof" is unsigned and the implicit conversions between "unsigned" numbers are consistent only with non-negative numbers. Therefore the undefined behavior should have been defined correspondingly. Instead of this, at…

[dead]
Post reply on HN