> silent unintended underflow behavior
Please show me an example in the wild that could not be trivially caught/alleviated. With 'trivially' I mean the code that needs to be written to prevent it, not the thinking you need to do to consider it.
As for the latter: this is what I get paid for. Writing the code out is necessary but not what I really get paid for (unless I were a very slow typist, that is).
I find that most of the time I was simply too lazy. Or rather: I wrote C/C++ code for 20+ years. I used int and didn't think (unintended rhyme).
Now I write (mostly) Rust I find myself considering the edge cases regularly and also covering them because the compiler forces me to. See also this comment [1].
I.e. a - 1 + b where a is always positive (incl. 0) and b is always > 1 'just' works with int (and unsigned [overflow] too!) in C/C++.
In Rust you will get a panic when a = 0 which will then make you think what you're doing and simply reorder this to a + b - 1.
I find that this is the 'cognitive load' that needs to be applied commonly and I'm pretty fine with that.
> dangers of mixed signed/unsigned code
Alleviated by simply not mixing. There is a reason languages like Rust simply do not allow this without explicit typecasts. And those, in cases where one type is signed and the other is not and they have equal width translate to "all bets are off".
> more cognitive load to read and understand unsigned underflow detection code [...]
See first point. IMHO this is simply the same point expressed differently. Underflow happens when you subtract.
Ensure you do not subtract a larger value from a smaller. This is as easy as writing max(a, b) - min(a, b) or what author of [1] does.
Same as abs(a - b) but works with unsigned. Cognitive load? I do not see any and I agree with the author of the article that this is easier to read.
[1] https://news.ycombinator.com/item?id=29767877