Or... just turn on warnings for comparing unsigned and signed types. It's not exactly hard.
Integer promotion rules suck, but you can just... turn on warnings for that.
The use documentation thing doesn't really make sense to me. "Don't put in documentation what you can put in types" is a very, very common rule for C++, and yet, you ask us to just put it in documentation for this specific set of types. "Use the types as documentation, *unless* you're dealing with integers, in which case just use documentation!"
strega-nil
I’d advise using a safe integer library instead of resorting to such advice.
A crude rule of thumb like this can lead the unwary to think they can just treat signed integers as having an infinite range, since it fixes one problem (comparison).
Mixing signed and unsigned values is just fine, if you’re already being careful of allowed ranges in your variables and types, which is essential.
If all you’re worried about is `a < b` in integer math in C++ you’re in for a big shock when you add, subtract, multiply or divide anything.
All of those go out of bounds in an undefined way with signed types, so you need careful bounds checking before all operations, or you need well-documented statements of the known range of quantities to be able to get by without them.
If you are relying on known ranges then you need to tie changes to the size of anything to also always checking your downstream assumptions.
Many a vulnerability has been caused by switching from 32 bit to 64 bit type widths and failing to update assumptions about arithmetic, for example.
paullhodgkinson
My question: where's James' response? Did he give a talk on the other side of the debate? *Is* there another side to the debate? :-)
davesteffen
Turn on warnings and cast to fix the warning.
lockbert
Say we have an size_t index in a loop and it overflows, using signed integer will 'solve' the problem with infinite looping, but it will not solve the actual problem which is that index exceeded its capacity, this is exactly a place for safe_ints, overflowing an index/counter is an exceptional situation and should be treated as such, not hidden behind a 'fix'. Other minor things as comparing signed with unsigned are well enough warned by the compiler and if developer is not fixing them then it is clearly not language's issue. So in general using signed integers in mentioned contexts does not solve a lot just is a good way to hide undesired behavior in your code.
JohnDoe-wbvp
Great argument Jon. I've been looking sideways at all the static_cast<int>'s littered throughout my code when doing math on my Area type which uses unsigned integers. Area can be zero but it can't be negative. This argument puts into words that nagging feeling I had in the back of my head.
Also, I have very recently fixed a production defect involving the underflow of unsigned index variables. Compiler warnings can't save you from bad maths, and if I have no ability to sanity check with idx < 0 things get out of hand very quickly.
qbradq
bitwise operations and math are mixed very often, especially when dealing with powers of 2. So, saying bitwise operations are for unsigned and math for signed doesn't really help at all. And yes sometimes you need the extra bit unsigned types have, especially on embedded systems where each bit counts and you have to use uint8_t and uint16_t all over the place.
In my opinion, the solution would be just to turn on compiler warnings for that case and if you get any warnings, cast the unsigned to its bigger signed counterpart.
embeddor
Two conflicting aspects. size_t is a better representation for something which cannot be negative. On the other hand one might underflow when using subtraction arithmetic on unsigned integers.
gast
This talk completely ignores that over/underflow is undefined behavior for signed types but not for unsigned types. For unsigned types calculations are performed mod 2^n. If you actually want these modulo calculations that is a very good reason to use unsigned numbers.
Apart from that I am just not buying it. As other commenters note there are warnings for comparing signed and unsigned numbers. Also, a size of a container being unsigned really does make a lot of sense. I do agree that using unsigned for bit fields is a good thing to do.
chrisdams
overflow checks: signed overflow is undefined behavior, unsigned overflow never occur (the result is modulu 2^N). So you can only do overflow checks with unsigned arithmetic.
urisimchoni
Would be nice if std::size_t could be replaced with a wrapper that behaves like a number and implements operator< intelligently.
StackedCrooked
With latest compilers and IDEs this is not such a bad deal to use unsigns for quantities.
dronx
I'm not very profecient in C++, but like he mentions using unsigned return type for a function is bad - is this the kind of problem a static analyzer can point out?
nilspin
This video has popups/overlays which obscure the content of the video. Did you not want us to actually understand the material being presented?
seanmccauliff
I've seen many cpp talks, but this one is just pure non sense. signed capacity() with a comment about undefined behaviour is better than unsigned capacity()? Who doesn't know what unsigned type is? Everyone learns that in the beginning. I am just astonished what absurd am I listening to.
ashrasmun
or, instead of listening to Jon Kalb... use "unsigned" or "size_t" when you need data that you don't want be represented with negative numbers... an example is a game with money system; unless you're going to implement a debt system, you're likely not going to need a signed data type for money if players start with 0 money and only goes back to 0... Using a signed integer for that money would mean you'd have to keep consistently range checking (unless again you want to add a debt system).