The problem with unsigned integer types is that, depending on their size, they can represent one of two different things:
- Unsigned types smaller than
int (for example, uint8 ) store numbers in the range 0..2ⁿ-1, and calculations with them will behave according to the rules of integer arithmetic if they do not exceed the range of type int . In accordance with these rules, if such a calculation exceeds the range of int , the compiler is allowed to do whatever he likes with the code, even if allowed to hide the laws of time and causality (some compilers will do just that!), And even if the result of the calculation will be returned to unsigned type smaller than int . - Unsigned types
unsigned int and larger hold elements of the abstract wrapping algebraic ring of integers, matching mod 2ⁿ; this effectively means that if the calculation falls outside the range 0..2ⁿ-1, the system will add or subtract any amount equal to 2ⁿ to get the value back in the range.
Therefore, with uint32_t x=1, y=2; xy expression can have one of two values depending on whether int more than 32 bits.
- If
int greater than 32 bits, the expression subtracts the number 2 from the number 1, giving the number -1. Please note that although a variable of type uint32_t cannot contain a value of -1, regardless of the size of int , saving either -1 will cause such a variable to contain 0xFFFFFFFF, but until or until the value is forcedly unsigned, it will behave like signed value -1. - If
int is 32 bits or less, the expression will give the value uint32_t , which when added to the value uint32_t will give the value uint32_t 1 (i.e. the value uint32_t 0xFFFFFFFF).
IMHO, this problem can be solved purely if C and C ++ were to define new unsigned types [for example. unum32_t and uwrap32_t], so that unum32_t will always behave like a number, regardless of the size of int (possibly requiring that the right subtraction or unary minus operation be raised to the next larger signed type if int is 32 bits or less), and wrap32_t will always behave like a member of an algebraic ring (blocking promotions, even if int was more than 32 bits). However, in the absence of such types, it is often impossible to write code that is portable and clean, since portable code often requires the use of types in all places.
supercat May 22 '15 at 17:45 2015-05-22 17:45
source share