# define math_errhandling implementation-defined
概要
math_errhandling
は、<cmath>
内の関数がエラーをどのように取り扱うかを表すマクロである。
取りうる値とその意味は以下の通り。
値 | 関数でエラーが発生した際の取り扱い |
---|---|
MATH_ERRNO |
エラー内容を errno に設定する。 |
MATH_ERREXCEPT |
エラー内容に応じた浮動小数点例外を発生させる。(C++ の例外ではない事に注意) |
MATH_ERRNO | MATH_ERREXCEPT |
上記の両方を行う。 |
備考
- 上記では「マクロ」としているが、規格上は外部リンケージの識別子であっても構わないとされている。
なお、その場合でもmath_errhandling
の値はプログラムの実行中は定数であり、実行中に変わる事はない。 math_errhandling & MATH_ERRNO
がゼロの場合にerrno
がどのようになるかは C99 規格(C++11、C++14 の参照規格)では明記されていないが、C11 ではmath_errhandling & MATH_ERRNO
が非ゼロの場合と同様に設定するか、全く変更しないかのいずれかである事が明記されている。- エラーが発生しなかった場合に
errno
がどのようになるかは C99 規格(C++11、C++14 の参照規格)では明記されていないが、C11 ではmath_errhandling
の値によらず変更されない事が明記されている。 - C99(C++11、C++14 の参照規格)では、処理系が ISO IEC 60559(IEEE 754 と等価)に準拠している場合、
math_errhandling & MATH_ERREXCEPT
は非ゼロと規定されている。
例
#include <iostream>
#include <cerrno>
#include <cstring>
#include <cfenv>
#include <cmath>
// エラー状態のクリア
void clearerr()
{
if (math_errhandling & MATH_ERREXCEPT) {
std::feclearexcept(FE_ALL_EXCEPT);
} else {
errno = 0;
}
}
// エラー状態の出力
void printerr()
{
if (math_errhandling & MATH_ERREXCEPT) {
int excepts = std::fetestexcept(FE_ALL_EXCEPT);
if (excepts & FE_INVALID) {
std::cout << "FE_INVALID\n";
}
if (excepts & FE_DIVBYZERO) {
std::cout << "FE_DIVBYZERO\n";
}
if (excepts & FE_OVERFLOW) {
std::cout << "FE_OVERFLOW\n";
}
if (excepts & FE_UNDERFLOW) {
std::cout << "FE_UNDERFLOW\n";
}
if (excepts & FE_INEXACT) {
std::cout << "FE_INEXACT\n";
}
} else {
int err = errno;
if (err != 0) {
std::cout << std::strerror(err) << '\n';
}
}
}
int main()
{
clearerr();
double result = std::log(0.0);
printerr();
std::cout << "log(0) = " << result << '\n';
}
出力例
FE_DIVBYZERO
log(0) = -inf
バージョン
言語
- C++11
処理系
- Clang: 3.0 ✅
- GCC: 4.3 ✅
- ICC: ??
- Visual C++: ??