サンプルコード (t91.c):
#include <stdio.h>
#include <fenv.h>
#if _MSC_VER
#pragma fenv_access (on)
#else
#pragma STDC FENV_ACCESS ON
#endif
void show_fe_exceptions(void)
{
printf("exceptions raised:");
if(fetestexcept(FE_DIVBYZERO)) printf(" FE_DIVBYZERO");
if(fetestexcept(FE_INEXACT)) printf(" FE_INEXACT");
if(fetestexcept(FE_INVALID)) printf(" FE_INVALID");
if(fetestexcept(FE_OVERFLOW)) printf(" FE_OVERFLOW");
if(fetestexcept(FE_UNDERFLOW)) printf(" FE_UNDERFLOW");
if(fetestexcept(FE_ALL_EXCEPT)==0) printf(" none");
printf("\n");
}
int main(void)
{
feraiseexcept(FE_OVERFLOW);
show_fe_exceptions();
return 0;
}
呼び出し:
$ clang t91.c -Wall -Wextra -pedantic && ./a.exe
t91.c:7:14: warning: pragma STDC FENV_ACCESS ON is not supported, ignoring pragma [-Wunknown-pragmas]
#pragma STDC FENV_ACCESS ON
^
1 warning generated.
exceptions raised: FE_OVERFLOW
$ gcc t91.c -Wall -Wextra -pedantic && ./a.exe
t91.c:7: warning: ignoring ‘#pragma STDC FENV_ACCESS’ [-Wunknown-pragmas]
7 | #pragma STDC FENV_ACCESS ON
|
exceptions raised: FE_OVERFLOW
$ cl t91.c /fp:strict && t91
exceptions raised: FE_INEXACT FE_OVERFLOW
ISO/IEC 9899:2011 (E):
7.6.2.2 fegetexceptflag 関数
feraiseexcept 関数が ''overflow'' または ''underflow'' 浮動小数点例外を発生させるたびに、さらに ''inexact'' 浮動小数点例外を発生させるかどうかは実装定義です。
ただし、gccのドキュメントと Microsoft Cのドキュメントには、関数の正確な動作が記載されていません (または見つかりません) feraiseexcept
。Clang/LLVMは、ソース コードを介して実装定義の動作を直接文書化することに注意してください。
また、ISO C 準拠の実装には、すべての実装定義およびロケール固有の特性とすべての拡張を定義するドキュメントが付随するものとします(ISO/IEC 9899:2011 (E)、セクション 4 パラグラフ 8)。
質問 (最後に!): なぜ C 実装は、実装定義の特性/動作をすべて文書化しないのですか?
アップデート。はい、GCC のマニュアルにはwrt Library Functionsと記載されています。これらのポイントのほとんどの動作は、C ライブラリの実装に依存しており、GCC 自体によって定義されていません。したがって、( for である) のglibc
実装を検討する必要があります。feraiseexcept
weak_alias
__feraiseexcept