...
Although the current text does not require narrowing return expressions of the same type as the function, it does not clearly stated state what is allowed. Is it allowed to narrow the result? Is it allowed to narrow the result sometimes but not always? Is it allowed to partially narrow the result (for example, if the ABI returns floats in double format, but a float function has a float return expression evaluated to wider than double)? An aggressive implementation could argue âyesâ to all these questions, though the resulting behavior would complicate debugging and error analysis.
Footnote 142 says a cast may be used to remove extra range and precision from the return expression. This means that a predictable program must have casts on all floating-point function calls (except where the function directly feeds an operator-like assignment that implies the conversion). With type-generic math (tgmath)
, the programmer has to reason through the tgmath
resolution rules to determine which casts to apply. These are significant obstacles to writing predictable code.
...
This noncompliant code example fails to cast the result of the expression in the return statement and thereby guarantee that the range or precision is no wider than expected. The uncertainty in this example is introduced by the constant 0.1f
. This constant may be stored with a range or precision that is greater than that of float
. Consequently, the result of x * 0.1f
may also have a range or precision greater than that of float
. As described above, this range or precision may not be reduced to that of a float
and, thus, the caller of calcPercentage()
may receive a value that is more precise than expected. This may lead to inconsistent program execution across different platforms.
...
Compliant Solution
This compliant solution remedies casts the value of the expression in the return statement. This forces the return value to have the expected range and precision as described in Section 5.2.4.2.2 8 of the C Standard.
...
Compliant Solution (Outside the function 1)
Forcing the range and precision inside the calcPercentage()
function is a good way to fix the problem once without having to apply fixes in multiple locations (every time calcPercentage()
is called). However, access to the called function may not always be available. This compliant solution shows one way to force the correct range and precision in a situation in which the source of the called function can not be modified. This is accomplished by casting the return value of the calcPercentage()
function to float
.
...