Part of the OpenSolaris source contains the following macro[1]:
41 /*
42 * FRC2PCT macro is used to convert 16-bit binary fractions in the range
43 * 0.0 to 1.0 with binary point to the right of the high order bit
44 * (i.e. 1.0 == 0x8000) to percentage value.
45 */
46
47 #define FRC2PCT(pp) (((float)(pp))/0x8000*100)
48
which gets called with 16-bit values of `pp', i.e. from members of a
structure, as in the prstat.c[2] snipper shown below:
482 static void
483 list_update(list_t *list, lwp_info_t *lwp)
484 {
...
513 id->id_pctcpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu);
But I recently discovered, by having a local program (which re-uses some
of the prstat Solaris source) crash when it reached that line from
list_update() that it's not always a good idea to blindly cast any
integer value to a float. Changing that macro to an inline function
that uses a `float' intermediate variable and re-arranging the
calculation a bit seems to have fixed the crash here:
static inline float
FRC2PCT(uint16_t pp)
{
float fval;
fval = (100.0 * pp) / 0x800;
return fval;
}
But I'm not sure why this breaks when the cast is used. Is casting an
integer value and then accessing it as a float something that causes UB
or even implementation-defined behavior?
- Giorgos
References:
***********
[1] http://cvs.opensolaris.org/source/xr...rstat/prstat.h
[2] http://cvs.opensolaris.org/source/xr...rstat/prstat.c