3

fenvオーバーフロー、アンダーフロー、不正確な結果などを生成するステートメントを探すために使用しています。

ただし、コンパイラがコードを並べ替えて、実際に必要な効果を実装しない可能性があると仮定するのは正しいですか? もしそうなら、関数の周りに「バリア」を作成するにはどうすればよいですかfe*(そうするための標準化された方法のボーナスポイントは?)揮発性ブロックをどこかにドロップできますか?

できればこれをテストするだけですが、方法がわかりません。

例:

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 */

編集:

それまでの間、揮発性ブロックを使用して、実質的にバリアを作成しています。

feclearexcept(FE_ALL_EXCEPT);

__asm__ volatile(
  "flds %2\n\t"
  "faddp\n\t"
  : "=&t" (result)
  : "f" (src1),
    "m" (src2)
);

if (fetestexcept(FE_ALL_EXCEPT))
  ...
4

1 に答える 1

1

面白い問題!このトピックについて議論しているこのページを見つけました。

#pragma STDC FENV_ACCESS ON

C99準拠のコンパイラで適切な処理を行います...これにはgccが含まれていません。ただし、不安定な回避策を使用しているようです。

そのページは、いくつかの gcc バグを示しており、そのうちの 1 つに問題を示すテスト プログラムがあります。

于 2013-04-01T00:36:20.843 に答える