#801·Bend

C lane F32.read accepts what the JS lane rejects: hex floats, nan(...), and a prefix accepted before an embedded NUL

Author: phenomenon0Created Sep 18, 2026Updated Sep 18, 2026

What you did

Ran the same file on both run lanes:

  • bend f32read.bend (JS lane)
  • bend f32read.bend -o f32read && ./f32read (native C lane)

What happened

input JS lane C lane
"0x1p0" none 1
"1\0junk" (embedded NUL) none 1
"nan(1)" none nan
"1.25junk" none none

("1.5" and "inf" agree on both lanes.)

The C lane accepts spellings the JS lane rejects: strtof reads 0x1p0 as a hex float and nan(1) as a NaN, and the embedded NUL ends the accepted prefix (the check is *end == 0 over a NUL-terminated buffer). The JS lane matches one regex against the whole string and returns None for all three. The two lanes should agree on the same input.

The file

bend
import Base

def show(m: Maybe<&2, F32>) -> String:
  match m:
    case Some{x}:
      F32.show(x)
    case None{}:
      "none"

def main() -> IO(Unit):
  do IO<Unit>:
    IO.print("hex=" ++ show(F32.read("0x1p0")))
    IO.print("nul=" ++ show(F32.read("1\0junk")))
    IO.print("nan_paren=" ++ show(F32.read("nan(1)")))
    IO.print("junk=" ++ show(F32.read("1.25junk")))

bend --version

bend 2.0.5 (2.0.4 the same)

uname -sm

Linux x86_64

clang --version (the first line)

clang version 21.1.7 (Fedora 21.1.7-1.fc43)

A fix for this exists on the fork phenomenon0/bend, branch archive/strings (one whole-extent grammar on both lanes).