What I need here is the effect of --checks:off with --overflowChecks:on but only for very specific parts of the program.
So, I thought about leaving the --overflowChecks:on part out when compiling and just add .push/.pop for the error, only when I need it:
{.push overflowChecks: on.}
# here we do want to catch OverflowDefect errors
{.pop.}
The problem is... the way Nim's code is structured, I doubt this construct (^above) has any effect whatsoever.
I mean... let's say I use * within the aforementioned block... I don't think it'll respect my pushed overflowChecks: on at all. As a matter of fact, by looking through Nim's code, I've found more than a few instances where the only thing being taken into account is the options that were passed when compiling. E.g.:
https://github.com/nim-lang/Nim/blob/devel/compiler/ccgexprs.nim#L581
So... the question is: is there any way I can selectively enable overflowChecks, only for some specific block of code? Or... would I have to re-implement even the most basic arithmetic routines for that purpose?
So...:
proc safeMulI*[T: SomeInteger](x: var T, y: T) {.inline, noSideEffect.} =
x = x * y
func safePow*[T: SomeNumber](x: T, y: Natural): T =
case y
of 0: result = 1
of 1: result = x
of 2: result = x * x
of 3: result = x * x * x
else:
var (x, y) = (x, y)
result = 1
while true:
if (y and 1) != 0:
safeMulI(result, x)
y = y shr 1
if y == 0:
break
safeMulI(x, x)
That looks kind of messy, but it definitely works.