3

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))
  ...
tj90241
  • 150
  • 6

1 Answers1

1

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.

rhashimoto
  • 15,650
  • 2
  • 52
  • 80
  • Good find on the bug report, I didn't see that one. Unfortunately, the `#pragma STDC FENV_ACCESS ON` in this situation only prevents the compiler from trying to fold constants (as to expose any floating point conditions to the runtime environment); as Richard said, there's likely no way to actually represent the use and define of the floating point status. Bummer. Looks like some inline assembly might be in order. – tj90241 Apr 01 '13 at 01:00