...
Code Block | ||||
---|---|---|---|---|
| ||||
void func(float f_a;) { int i_a; /* Initialize float f_a */ i_a = f_a; /* Undefined if the integral part of f_a > INT_MAX */ i_a = f_a; } |
Compliant Solution (Int-Float)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> void func(float f_a;) { int i_a; /* Initialize float f_a */ if (f_a > (float) INT_MAX || f_a < (float) INT_MIN) { /* Handle error */ } else { i_a = f_a; } } |
Noncompliant Code Example (Demotions)
...
Code Block | ||||
---|---|---|---|---|
| ||||
void func(double d_a, long double big_d;) { double d_a; double d_b; float f_a = (float)big_d; float f_b; /* Initializations */ float f_a = (float)d_a; float f_b = (float)big_d; d_b = (double)big_d;} |
As a result of these conversions, it is possible that d_a
is outside the range of values that can be represented by a float or that big_d
is outside the range of values that can be represented as either a float
or a double
. If this is the case, the result is undefined.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <float.h> void func(double d_a, long double big_d;) { double d_a; double d_b; float f_a; float f_b; /* Initializations */ if (d_a > FLT_MAX || d_a < -FLT_MAX) { /* Handle error condition */ } else { f_a = (float)d_a; } if (big_d > FLT_MAX || big_d < -FLT_MAX) { /* Handle error condition */ } else { f_b = (float)big_d; } if (big_d > DBL_MAX || big_d < -DBL_MAX) { /* Handle error condition */ } else { d_b = (double)big_d; } } |
Risk Assessment
Failing to check that a floating-point value fits within a demoted type can result in a value too large to be represented by the new type, resulting in undefined behavior.
...
[IEEE 754] | IEEE 754-1985 Standard for Binary Floating-Point Arithmetic |
[ISO/IEC 9899:2011] | Subclause 6.3.1.4, "Real Floating and Integer" Subclause 6.3.1.5, "Real Floating Types" Annex J, J.2, "Undefined behavior" |
...