...
Wiki Markup |
---|
The C99 standard \[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\] states in Section 6.8.6.4, Paragraph 3, |
If a return statement with an expression is executed, the value of the expression is returned to the caller as the value of the function call expression. 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.142)
This paragraph is footnoted as follows:
142) 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. A cast may be used to remove this extra range and precision.
Conversion as if by assignment to the type of the function is required if the return expression has a different type than the function, but not if the return expression has a wider value only because of wide evaluation. This allows seemingly inconsistent and confusing behavior. Consider for the following code as an example:
Code Block |
---|
float f(float x) {   return x * 0.1f; } float g(float x) {   return x * 0.1; } |
...
Code Block | ||
---|---|---|
| ||
float calcPercentage(float value) { volatile float result; result = value * 0.1f;   return result; } void floatRoutine(void) { float value = 99.0f; long double percentage; percentage = calcPercentage(value); } |
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 cannot be modified. This is accomplished by casting the return value of the calcPercentage()
function to float
.
Code Block | ||
---|---|---|
| ||
void floatRoutine(void) { float value = 99.0f; long double percentage; percentage = (float)calcPercentage(value); } |
Compliant Solution (Outside the
...
Function 2)
This compliant solution shows another way to force the correct range and precision. In this case, a temporary variable is used as the forcing mechanism.
...