Repository navigation
C17/C23: "floating constant is out of range" for 1e10000, which is in range when double has infinities #189
Replies: 1 comment
|
New findings, which widen this report beyond C17 and C23. A search of glibc's history shows where DR #25 (1992) asked what "representable floating-point value" means. The committee's response:
and
The constraint it reads is in every C dialect. C90 6.1.3: "The value of a constant shall be in the range of representable values for its type." C99 6.4.4p2 and C11 6.4.4p2 keep the same requirement. C17 5.2.4.2.2p5 later wrote the answer into the standard. So 1e10000 is in range in C89, C99 and C11 as well, and those strict modes give the same error: gcc accepts the constant under So the fix asked for here should cover the C89, C99 and C11 modes as well as C17 and C23. |
Uh oh!
There was an error while loading. Please reload this page.
Issue Summary
double h = 1e10000;is rejected with error #30 (bad_float_value) in--c17and--c23modes. C17 5.2.4.2.2p5 and C23 5.2.5.3.3p19 say that if positive infinity is representable in a floating type, the range of that type extends to all positive real numbers. On x86_64doublehas an infinity, so 1e10000 is within the range of representable values, the constraint in C17 6.4.4p2 (C23 6.4.4.1p2) is met, and the constant is valid.EDG already gives such constants their C17 meaning under GNU emulation:
conv_host_fp_to_double(src/float_pt.c:1067-1068) reports the overflow unlessgnu_modeis set, and in that mode "GNU C and C++ silently uses infinity for values that are too large". In C17 that is one of the results 6.4.4.2p3 allows (the nearest representable value or one adjacent to it), and the one 6.4.4.2p7 recommends: translation should matchstrtod, which returns infinity for this input.This matters in practice: glibc's
<math.h>definesHUGE_VALas1e10000for compilers that do not define__GNUC__, so outside GNU emulationHUGE_VALcannot be used.Observed Behavior
cpfe built from the
linux-gcc-releasepreset, run with the repository's own base:The same error appears without
-A(cpfe --c17 big.c). The diagnostic is not discretionary:cpfe --c17 -A --diag_warning=30 big.cstill reports the error. Under GNU emulation the constant is accepted:cpfe --gcc big.creports nothing.Expected Behavior
The constant is accepted in C17 and C23 modes, for instance converted to infinity as under GNU emulation. A warning would be fine:
gcc -std=c17 -pedantic-errors -c big.caccepts it with only a-Woverflowwarning.C99 and C11 do not define the range of a floating type with infinities, so this report is limited to C17 and C23.
Additional Details
ca5890bab8, x86_64 Linux.Configuration:
cpfe --dump_configurationoutput attached: dump_configuration.txtAll reactions