Skip to content

A float literal outside its type's range is accepted: f32 a <- 1e39f32 emits 1e39f, which gcc -Werror rejects (exit 0) #2002

Description

@jlaustill

The defect

A float literal whose value is outside its type's range transpiles with exit 0 on every target. The generated C then fails the -Werror compile that every fixture cell uses, or holds a different value from the one written.

Measured on main at 0cd96994b with npx tsx src/cli/index.ts <file> --target host, then gcc -c -O3 -Wall -Wextra -Werror (the // test-no-warnings flags). g++ -x c++ with the same flags gives the same errors.

program C-Next emitted gcc -Werror
f32 a <- 1e39f32; exit 0 float a = 1e39f; error: floating constant exceeds range of 'float' [-Werror=overflow]
f32 c <- 1e-50f32; exit 0 float c = 1e-50f; error: floating constant truncated to zero [-Werror=overflow]
f64 d <- 1e309; exit 0 double d = 1e309; error: floating constant exceeds range of 'double' [-Werror=overflow]
f32 b <- 1e39; exit 0 float b = 1e39; no diagnostic; b holds inf

Without -Werror, the first three only warn, and the program holds inf or 0.0f where it wrote 1e39, 1e-50 or 1e309. The fourth is an f64 literal converted to float. C11 6.3.1.5p1 leaves the conversion of a value outside the destination's range undefined, and Annex F gives inf.

Controls (in range, must stay accepted): f32 ok1 <- 3.4e38f32; and f32 ok2 <- 1e-38f32; transpile with exit 0 and compile cleanly under the same flags.

Reproduction

suffixed.cnx:

f32 a <- 1e39f32;
u32 main() {
    if (a < 1.0f32) { return 1; }
    return 0;
}
npx tsx src/cli/index.ts suffixed.cnx --target host   # exit 0
gcc -c -O3 -Wall -Wextra -Werror suffixed.c           # error: floating constant exceeds range of 'float'

What needs deciding

No ADR decides this. E0868 (ADR-024) rejects an integer literal that does not fit its target's range. ADR-044 "Floating Point Literals" says only that an unsuffixed literal is f64 and that narrowing it to f32 "loses precision". It says nothing about a value outside the type's range, or one that rounds to zero.

Related

Definition of done

  • The owner decides, in ADR-044 or ADR-024, whether a float literal outside its type's range is a transpile-time diagnostic. That covers overflow to inf and rounding to zero, for a suffixed literal and for an unsuffixed literal converted to f32.
  • Each row above either has that diagnostic, with a test-error fixture that keeps the in-range controls beside it, or has a reason recorded here for leaving it to the C compiler.
  • Mutation-checked: removing the check turns the fixture red.

Activity

  1. added
    bugSomething isn't working
    typesType system issues
    validation-bugMissing compile-time validation
    on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtypesType system issuesvalidation-bugMissing compile-time validation

    Projects

    • Status
      Grooming

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions