Document number: P0586R0
Date: 2017-09-12
Project: Programming Language C++
Reply-to: Federico Kircheis
Audience: Library Evolution Working Group

Safe integral comparisons

I. Table of Contents

II. Motivation

Comparing integrals of different types may be a more complex task than expected. Most of the time we expect that a simple

	if(a < b){
		// ...
	} else {
		// ...
	}

should work in all cases, but if a and b are of different types, things are more complicated.
If a is a signed type, and b unsigned, then a is converted to the unsigned type. If a held a number less than zero, then the result may be unexpected, since the expression a < b could evaluate to false, even if a strictly negative number is always lower than a positive one.

Also converting integrals between different types can be challenging, for simplicity, most of the time we assume that values are in range, and write

	a = static_cast<decltype(a)>(b);

If we want to write a safe conversion, we need to check if b has a value between std::numeric_limits<decltype(a)>::min() and std::numeric_limits<decltype(a)>::max(). We also need to pay attention that no implicit conversion (for example between unsigned and signed types) invalidates our comparison.

Comparing and converting numbers, even of different numeric types, should be a trivial task. Unfortunately it is not, and because of implicit conversions we may write, without noticing it, unsafe code.

III. Proposal

This paper proposes to add a set of constexpr and noexcept functions for converting and comparing integrals of different signeddes (except for bool):