Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Incorrect overflow/underflow error in case statements #11551
The below snippet used to work correctly before Nim 0.20.0:
proc negativeOrNot(num: int): string = result = case num of low(int) .. -1: "negative" else: "zero or positive" echo negativeOrNot(-1) echo negativeOrNot(10000000) echo negativeOrNot(0)
Interestingly, this works:
proc negativeOrNot(num: int): string = result = case num # of low(int) .. -1: # Error: unhandled exception: over- or underflow [OverflowError] # of (low(int)+1) .. -1: # Error: unhandled exception: over- or underflow [OverflowError] of (low(int)+2) .. -1: # works "negative" else: "zero or positive" echo negativeOrNot(-1) echo negativeOrNot(10000000) echo negativeOrNot(0)
It's not clear why
If you go to https://scripter.co/notes/nim/#case-statements and scroll down a bit to the
That example is originally from https://nim-by-example.github.io/case/.
Before when we overflowed the result would be requiring an else even if not necessary, which is why your example worked. Edit: to clarify, this error is just about getting the code through sem, and doesn't effect runtime results.
There a couple places where improvements could be made to case, ones i've found:
# Error: unhandled exception: over- or underflow [OverflowError] case 1: of low(int)..high(int): discard # use to require else instead of erroring. # Invalid values for type, there are a couple variations with invalid types. case range[1..1](1): of 2: discard # Error: expression '"empty"' is of type 'string' and has to be discarded # use efWantValue for a better error var x = case "1": of "": "empty"
The way case coverage is checked is seeing if the length of the ordinal type matches the sum of the lengths of the branch values. Possible solutions: using
@narimiran I wouldn't want to have code deployed with overflow checks disabled.
The root question is why is it overflowing/underflowing at
Also the mysterious behavior with ..
The issue is that the number of cases covered in a case statement/expression is stored in a
proc foo(T: typedesc) = var x: T case x of low(T) .. high(T): discard foo(int8) # Works foo(int64) # 'not all cases are covered' with -d:danger, otherwise overflow