Submitter:Fred J. Tydeman
Submission Date:2017-09-27
Document: WG14 N2172
While the type returned by this code:
float tenth(void) return 1.F / 10.F;
is float, the value (or format or representation) returned
could be 0.1F, 0.1, or 0.1L depending upon how '/' is evaluated and
how return of wider precision is done.
In addition, while the type returned by this code:
float _Complex Ctenth(void) return (1.f + 0.f*I) / 10.f;
is float _Complex, the value (or format or representation)
returned for the real part need not be the same as the other
function.
The return of a floating-point value from a function via the return statement (6.8.6.4) has changed over the years. C89, C90, C95, and C99 made no mention of extra range and precision. TC3 to C99 added both FLT_EVAL_METHOD and extra range and precision to the footnote (due to N1017). C11 removed FLT_EVAL_METHOD from that footnote (due to N1382).
In addition, Annex F has also changed. Before C11, nothing was mentioned about return. Then in C11, F.6 was added to require extra range and precision to be removed (due to N1396).
Currently, there is no way for an application to find out (which, if any) return statements remove or keep extra range and precision. Also, there is no requirment that all the returns be consistent in what they do; some functions might remove while others keep extra range or precision (something I have noticed in my testing of math libraries and compilers).
Some implementations that return extra range and precision for real floating-point, do not return extra range and precision for complex.
To make programs more portable and consistent, the standard should require that all extra range and precision be removed by a return statement (just like an assignment and a cast).
Existing implementations that return widened results can still return widened results, but those results must have been passed thru the knothole of a cast or assignment to remove all the extra range and precision.
Suggested change:
6.8.6.4 The return statement, paragraph 3 has:
If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.160)
160) The return statement is not an assignment. The overlap restriction of subclause 6.5.16.1 does not apply to the case of function return. The representation of floating-point values may have wider range or precision than implied by the type; a cast may be used to remove this extra range and precision.
Change those to:
The expression is converted as if by assignment to an object having the return type of the function.160)
160) The return statement is not an assignment. The overlap restriction of subclause 6.5.16.1 does not apply to the case of function return.