Description
As noted in discussion on #4075, there are currently places in the codebase where we are using signed integers for positive indexing or to represent container sizes or other quantities that are better represented by other types (generally std::size_t
). In order to clearly signal the semantic meaning of these variables, avoid signed/unsigned casting and comparisons, and to reduce the likelihood of overflow/underflow bugs, I propose the following rules:
- Avoid raw indexed loops wherever possible, instead giving preference to the relevant STL algorithm
- Always represent the size of an STL container with
some_container<T>::size_type
and use the same type for raw positive indexing. Liberal use ofauto
should make this less onerous, and rule 1 should make it rare. - When representing the size of a quantity other than the size of a container or doing any other kind of raw positive indexing, use
std::size_t
unless there is a clear performance/resource reason to use a smaller type. In this case, an unsigned integer of the desired size should be used explicitly (e.g.uint32_t
) and a comment should be added where the variable is declared explaining the performance consideration. If this is necessary for a custom container, aliascustom_container<T>::size_type
to the selected integer type. - For negative indexing, the same basic rules apply. Use
iterator::difference_type
where possible or explicitly invokestd::ptrdiff_t
otherwise. - Use
int
to represent mathematical integers, quantities which can take on negative values and which are not sizes or indexes. A signed integer should not be used simply to include-1
as a special case; preferstd::optional
or other ways of signaling this more clearly.
If we are better about rule 1, rules 2-5 should become less and less relevant.
TL;DR version:
- for-loops bad, algorithms good
container::size_type
for sizes and positive indexing where possible,std::size_t
otherwiseiterator::difference_type
for negative indexing where possible,std::ptrdiff_t
otherwiseint
is a mathematical quantity, not a size or an index- Performance exceptions are always allowed, but be explicit about them
I'm not married to these rules, but they seem like a reasonably small and complete set that is consistent with other style and usage guidelines. We can use this issue for any necessary discussion until #4075 is merged, and then I'll be happy to work on implementing whatever we land on.