fenv_access
pragma
浮動小数点環境フラグのテストとモードの変更を変更する可能性がある (on
) 最適化を無効にするか、(off
) 最適化を有効にします。
構文
#pragma fenv_access (
{on
|off
})
解説
既定では、fenv_access
は off
です。 コンパイラは、コードが浮動小数点環境にアクセスまたは操作しないと想定しています。 環境へのアクセスが必要ない場合、コンパイラは浮動小数点コードを最適化するためにさらに多くのことを行えます。
コードが浮動小数点状態フラグ、例外、または制御モード フラグを設定する場合に、fenv_access
を有効にします。 コンパイラは浮動小数点の最適化を無効にし、コードが浮動小数点環境に一貫してアクセスできるようします。
/fp:strict
コマンドライン オプションを使用すると、fenv_access
が自動的に有効になります。 この動作と他の浮動小数点動作の詳細については、/fp (浮動小数点数動作の指定) を参照してください。
fenv_access
pragma を他の浮動小数点設定と組み合わせて使用する方法には制限があります。
正確なセマンティクスが有効になっていない限り、
fenv_access
を有効にすることはできません。 正確なセマンティクスは、float_control
または pragma のいずれかによって、または/fp:precise
か/fp:strict
コンパイラ オプションを使用して有効にできます。 他の浮動小数点コマンド ライン オプションが指定されていない場合、コンパイラは既定で/fp:precise
に設定されます。fenv_access(on)
が設定されている場合は、float_control
を使用して正確なセマンティクスを無効にすることはできません。
fenv_access(on)
ディレクティブは、浮動小数点演算を組み合わせる機械命令である浮動小数点数の縮約の生成を無効にします。 fenv_access(off)
は、縮約の前の動作を復元します。 この動作は、Visual Studio 2022 での新機能です。 以前のバージョンのコンパイラは、fenv_access(on)
が指定されると既定で縮約を生成できました。 浮動小数点の縮約の詳細については、「/fp:contract
」を参照してください。
fenv_access
の影響を受ける最適化の種類は次のとおりです。
グローバルの共通部分式の削除
コードの移動
定数の折りたたみ
その他の浮動小数点 pragma ディレクティブは次のとおりです。
例
この例では、fenv_access
を on
に設定して、浮動小数点コントロール レジスタに 24 ビットの有効桁数を設定します。
// pragma_directive_fenv_access_x86.cpp
// compile with: /O2 /arch:IA32
// processor: x86
#include <stdio.h>
#include <float.h>
#include <errno.h>
#pragma fenv_access (on)
int main() {
double z, b = 0.1, t = 0.1;
unsigned int currentControl;
errno_t err;
err = _controlfp_s(¤tControl, _PC_24, _MCW_PC);
if (err != 0) {
printf_s("The function _controlfp_s failed!\n");
return -1;
}
z = b * t;
printf_s ("out=%.15e\n",z);
}
out=9.999999776482582e-03
前のサンプルから #pragma fenv_access (on)
をコメント アウトした場合、出力は異なります。 これは、コンパイラが制御モードを使用しないコンパイル時の評価を行うためです。
// pragma_directive_fenv_access_2.cpp
// compile with: /O2 /arch:IA32
#include <stdio.h>
#include <float.h>
int main() {
double z, b = 0.1, t = 0.1;
unsigned int currentControl;
errno_t err;
err = _controlfp_s(¤tControl, _PC_24, _MCW_PC);
if (err != 0) {
printf_s("The function _controlfp_s failed!\n");
return -1;
}
z = b * t;
printf_s ("out=%.15e\n",z);
}
out=1.000000000000000e-02