I'm using fenv
to look for statements which produce overflows, underflows, inexact results, etc.
However, am I correct in assuming that the compiler could reorder code on me and not implement the effect I actually desire? If so, how would I go about creating a "barrier" around the fe*
functions (bonus points for standardized methods of doing so?) Can I just drop a volatile block in somewhere?
I would just test this if I could, but I'm unsure of how.
Example:
void some_function(double d) {
float f;
feclearexcept(FE_ALL_EXCEPT)
f = d; /* will the relevant code for this statement be inserted exactly here? */
if (fegetexcept(FE_ALL_EXCEPT))
printf("FP condition raised during conversion from double to float.\n");
}
/* desired behaviour: */
some_function(DBL_MAX); /* should cause printf to execute */
some_function(FLT_MAX); /* should not cause printf to execute */
EDIT:
In the meantime, I'm using volatile blocks to, in effect, create a barrier.
feclearexcept(FE_ALL_EXCEPT);
__asm__ volatile(
"flds %2\n\t"
"faddp\n\t"
: "=&t" (result)
: "f" (src1),
"m" (src2)
);
if (fetestexcept(FE_ALL_EXCEPT))
...
Interesting problem! I found this page discussing the topic, and it says that adding
#pragma STDC FENV_ACCESS ON
will do the proper thing on a C99 conforming compiler...which does not include gcc. You appear to be right on with the volatile workaround, though.
That page points to a couple of gcc bugs, one of which has a test program that demonstrates the issue.