nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.44k stars 1.47k forks source link

float to char (or uint8 etc) invokes undefined behavior and produces random results (eg: `char(255.0)`) #18540

Open timotheecour opened 3 years ago

timotheecour commented 3 years ago

Example 1

when true:
  proc c_printf*(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>", varargs, discardable.}
  let num = 256.1
  let a1 = uint8(num)
  when defined case3c_sub:
    echo ord(uint8(num))
  let a2 = ord(uint8(num))
  c_printf("%d\n", a1.cint)
  c_printf("%d\n", a2.cint)

Current Output

nim r main 216 0

nim r -d:case3c_sub main 208 0

nim r -b:cpp main 0 0

nim r -d:danger main 0 0

Expected Output

Example 2

when true:
  let num = 255.0
  echo ord(char(num))
  let z = char(num)
  echo (z, ord(z))

nim r main 0 ('\x98', 152)

nim r -b:cpp 255 ('\xFF', 255)

nim r -d:danger 0 ('\x00', 0)

Additional Information

1.5.1 73ce40aaf71196faa08072216bd826a94b5d40b1 root cause for https://github.com/nim-lang/Nim/issues/10421 which I've just closed in favor of this issue

links

https://frama-c.com/2013/10/09/Overflow-float-integer.html

Araq commented 3 years ago

Pretty simple to fix as Nim can already generate a union for this case.