Oftentimes, programming languages assign sizes to certain numeric types: in C,
the 8-bit unsigned integer is called
uint8_t, and can represent values
between 0 and 255. If something larger than 255 is assigned to a variable of
this type, it rolls over, the result being the modulus. So if we assigned 260
uint8_t, we would actually get 5 instead. If we were to do this to an
int8_t (the 8-bit signed integer that represents values from -127 to 127),
the results are undefined; a C compiler has license to do whatever it likes.
This has a couple of unfortunate effects. The first is you constantly need to
estimate what values may be stored in your variables, which generally causes
most programmers to use
int everywhere. The second is when numbers behave
unexpectedly (roll over or explode), they can cause program misbehavior, which
often leads to a crash or a security issue.
Ki has two number types that are not like this:
uint. They are
intended to be the default integer types. Instead of overflowing, they just
keep growing (either positively or negatively). The downside is that they
become about half as fast as a regular integer once they exceed the bit-width
of the host machine.
The other integer types (
u64) don't do this, rather they overflow by default. Signed overflow is
well-defined in Ki; it doesn't share that problem with C.
You can change the overflow behavior of both
int and the sized integer types
at a program level or an expression level. Here are your options:
@overflow.: calls the function
xwith the pre-overflow value
@overflowfn: used to define an overflow handling function instead of
@set_overflow_handler: sets the default overflow handler to the function
@overflow.bignum: convert to bignum (probably default policy)
@overflow.error: runtime error
@overflow(: custom function