プログラミング/C++/C++11 既存ライブラリ変更点/C言語互換 のバックアップ(No.1)


C++03規格時点で存在したC言語互換ライブラリに対するC++11規格での変更点をまとめています。

概要

当文書では、C言語互換ヘッダファイル群について、C++11規格での変更点をまとめている。

C言語互換ヘッダファイル名は、C言語標準のヘッダファイル名から拡張子 .h を削除し、頭に c を付けた形で命名されている。(例: <stdio.h> → <cstdio>)
定義されている内容はほとんどC言語のものと同じだが、下記のような違いがある。

  • あらゆる要素は名前空間 std 内で定義される。

    • 処理系によっては、C言語用のヘッダファイルをインクルードした上で各要素を名前空間 std 内で using 宣言する形で定義されており、各要素をグローバル名前空間でも利用可能な場合がある。
      例えばそのような処理系で <cstdio> をインクルードすると、関数 printfstd::printf としても ::printf としても利用可能となる。
      ただしC++言語ではグローバル名前空間に定義された要素の利用は推奨されない。
  • 関数オーバロードが定義されている場合がある。
    例えば cos に対する cosfcosl 等のC言語では別名定義されている関数が、オーバロードによって単一の関数名にまとめられている。

<cassert>

変更点なし。

<cctype>

  • 下記の関数が追加された。

    // 文字 c が空白文字ならば 0 以外の値を返す。そうでなければ 0 を返す。
    int isblank(int c);

<cerrno>

変更点なし。

<cfloat>

  • 下記のマクロ定数が定義された。

    DECIMAL_DIG
    FLT_DIGDBL_DIGLDBL_DIG の中で最大の値。
    FLT_EVAL_METHOD
    処理系において実数型がどのように評価されるかを示す。
    • 値が 0 の場合、各々の型を各々の型のまま評価する。
    • 値が 1 の場合、 floatdouble として評価される。
    • 値が 2 の場合、 floatdoublelong double として評価される。
    • 値が -1 の場合は評価方法を決定できない。
    • 値が -2 以下の場合は処理系依存。

<ciso646>

変更点なし。

<climits>

  • 下記のマクロ定数が定義された。

    LLONG_MIN
    long long int 型で表すことのできる最小の数値。 -9223372036854775807 以下の値となる。
    LLONG_MAX
    long long int 型で表すことのできる最大の数値。 9223372036854775807 以上の値となる。
    ULLONG_MAX
    unsigned long long int 型で表すことのできる最大の数値。 18446744073709551615 以上の値となる。

<clocale>

lconv 構造体

  • 下記のメンバ変数が定義された。

    // 国際通貨文字列フォーマットにおいて、非負および負の金額値に対して
    // メンバ変数 int_curr_symbol の文字列を前置するならば 1 、後置するならば 0 。
    char int_p_cs_precedes;     // 非負の金額値用
    char int_n_cs_precedes;     // 負の金額値用
    
    // 国際通貨文字列フォーマットにおいて、非負および負の金額値に対して
    // メンバ変数 int_curr_symbol の文字列、符号、数値をどう区切るか示す値。
    // 値の意味はメンバ変数 p_sep_by_space および n_sep_by_space に準じる。
    char int_p_sep_by_space;    // 非負の金額値用
    char int_n_sep_by_space;    // 負の金額値用
    
    // 国際通貨文字列フォーマットにおいて、非負および負の金額値に対して
    // メンバ変数 positive_sign あるいは negative_sign の文字列をどう配置するか示す値。
    // 値の意味はメンバ変数 p_sign_posn および n_sign_posn に準じる。
    char int_p_sign_posn;       // 非負の金額値用
    char int_n_sign_posn;       // 負の金額値用
    

<cmath>

文中で登場する型名については下記のように定まる。

  • 関数の引数の型名が integral で始まるものは、任意の整数型を引数に取ることを表す。
  • 関数の引数の型名が arithmetric で始まるものは、任意の整数型または実数型を引数に取ることを表す。
  • 関数の戻り値の型名が arithmetric となっているものは次の規則に従って型が定まる。
    1. いずれかの引数の型が long double ならば long double
    2. いずれかの引数の型が doublefloat 、または整数型ならば double
    3. 上記以外ならば未定義。(コンパイルエラー)

実際の関数定義方法は処理系依存だが、一般的には関数テンプレートとして定義される。

  • float_t 型および double_t 型が定義された。

    #if FLT_EVAL_METHOD == 0
    typedef float  float_t;
    typedef double double_t;
    #elif FLT_EVAL_METHOD == 1
    typedef double float_t;
    typedef double double_t;
    #elif FLT_EVAL_METHOD == 2
    typedef long double float_t;
    typedef long double double_t;
    #else
    // 処理系依存
    #endif
  • 下記の関数が定義された。

    // 逆双曲線余弦(アークハイパボリックコサイン)を算出する。
    float acosh(float value);
    double acosh(double value);
    long double acosh(long double value);
    double acosh(integral value);
    // 逆双曲線正弦(アークハイパボリックサイン)を算出する。
    float asinh(float value);
    double asinh(double value);
    long double asinh(long double value);
    double asinh(integral value);
    // 逆双曲線正接(アークハイパボリックタンジェント)を算出する。
    float atanh(float value);
    double atanh(double value);
    long double atanh(long double value);
    double atanh(integral value);
    ]}
    #code(c,nomenu,nonumber,nooutline,noliteral,nocomment){{
    // 2 の value 乗を算出する。
    float exp2(float value);
    double exp2(double value);
    long double exp2(long double value);
    double exp2(integral value);
    // ネイピア数 e の value 乗から 1 を引いた値を算出する。
    // value が 0 に近いほど (exp(value) - 1) よりも高精度になる。
    float expm1(float value);
    double expm1(double value);
    long double expm1(long double value);
    double expm1(integral value);
    // value の指数部を整数値として取得する。
    int ilogb(float value);
    int ilogb(double value);
    int ilogb(long double value);
    int ilogb(integral value);
    // value に 1 を足した値の、ネイピア数 e を底とする自然対数を算出する。
    // value が 0 に近いほど log(1 + value) よりも高精度になる。
    float log1p(float value);
    double log1p(double value);
    long double log1p(long double value);
    double log1p(integral value);
    // 2 を底とする二進対数を算出する。
    float log2(float value);
    double log2(double value);
    long double log2(long double value);
    double log2(integral value);
    // value の指数部を取得する。
    float logb(float value);
    double logb(double value);
    long double logb(long double value);
    double logb(integral value);
    // (value * pow(FLT_RADIX, expo)) 相当の値を算出する。
    float scalbn(float value, int expo);
    double scalbn(double value, int expo);
    long double scalbn(long double value, int expo);
    double scalbn(integral value, int expo);
    // (value * pow(FLT_RADIX, expo)) 相当の値を算出する。
    // 第2引数の型が long になったこと以外は scalbn と同じ。
    float scalbln(float value, long expo);
    double scalbln(double value, long expo);
    long double scalbln(long double value, long expo);
    double scalbln(integral value, long expo);
    // value の立方根を算出する。
    float cbrt(float value);
    double cbrt(double value);
    long double cbrt(long double value);
    double cbrt(integral value);
    // ((value1 * value1) + (value2 * value2)) の平方根を返す。
    // 2次元平面上の2点間の直線距離を求める時などに便利。
    // 点(x1,y1)と点(x2,y2)の直線距離は hypot(x2-x1, y2-y1) で求まる。
    float hypot(float value1, float value2);
    double hypot(double value1, double value2);
    long double hypot(long double value1, long double value2);
    arithmetric hypot(arithmetric1 value1, arithmetric2 value2);
    // value の誤差関数値を算出する。
    float erf(float value);
    double erf(double value);
    long double erf(long double value);
    double erf(integral value);
    // value の相補誤差関数値を算出する。
    float erfc(float value);
    double erfc(double value);
    long double erfc(long double value);
    double erfc(integral value);
    // value のガンマ関数値を算出する。
    float tgamma(float value);
    double tgamma(double value);
    long double tgamma(long double value);
    double tgamma(integral value);
    // value のガンマ関数値の自然対数を算出する。
    float lgamma(float value);
    double lgamma(double value);
    long double lgamma(long double value);
    double lgamma(integral value);
    // value 以下の最も value に近い整数値を取得する。
    float trunc(float value);
    double trunc(double value);
    long double trunc(long double value);
    double trunc(integral value);
    // value を四捨五入した値を取得する。
    // 小数部の絶対値がちょうど 0.5 の場合、 0 から離れる方向に丸められる。
    // 即ち round(1.5) は 2.0 となり、 round(-1.5); は -2.0 となる。
    float round(float value);
    double round(double value);
    long double round(long double value);
    double round(integral value);
    // value を四捨五入した値を取得する。
    // 戻り値の型が long になったこと以外は round と同じ。
    long lround(float value);
    long lround(double value);
    long lround(long double value);
    long lround(integral value);
    // value を四捨五入した値を取得する。
    // 戻り値の型が long long になったこと以外は round と同じ。
    long long llround(float value);
    long long llround(double value);
    long long llround(long double value);
    long long llround(integral value);
    // value に現在の丸めモードによる整数値への丸めを施した値を取得する。
    float nearbyint(float value);
    double nearbyint(double value);
    long double nearbyint(long double value);
    double nearbyint(integral value);
    // value に現在の丸めモードによる整数値への丸めを施した値を取得する。
    // 戻り値の型が int になったこと以外は nearbyint と同じ。
    int rint(float value);
    int rint(double value);
    int rint(long double value);
    int rint(integral value);
    // value に現在の丸めモードによる整数値への丸めを施した値を取得する。
    // 戻り値の型が long になったこと以外は nearbyint と同じ。
    long lrint(float value);
    long lrint(double value);
    long lrint(long double value);
    long lrint(integral value);
    // value に現在の丸めモードによる整数値への丸めを施した値を取得する。
    // 戻り値の型が long long になったこと以外は nearbyint と同じ。
    long long llrint(float value);
    long long llrint(double value);
    long long llrint(long double value);
    long long llrint(integral value);
    // (numer / denom) の剰余を算出する。
    // 類似の関数である fmod は常に 0 以上の値を返すが、
    // この関数は (fmod(numer, denom) > denom / 2) を満たす場合に負数を返す。
    float remainder(float numer, float denom);
    double remainder(double numer, double denom);
    long double remainder(long double numer, long double denom);
    arithmetric remainder(arithmetric1 numer, arithmetric2 denom);
    // remainder(numer, denum) と等価の値を返す。
    // また (numer / denum) の商を quot に設定する。
    float remquo(float numer, float denom, int* quot);
    double remquo(double numer, double denom, int* quot);
    long double remquo(long double numer, long double denom, int* quot);
    arithmetric remquo(arithmetric1 numer, arithmetric2 denom, int* quot);
    // magni の絶対値に sign の符号を付けた値を取得する。
    // (signbit(sign) ? -abs(magni) : abs(magni)) に相当する。
    float copysign(float magni, float sign);
    double copysign(double magni, double sign);
    long double copysign(long double magni, long double sign);
    arithmetric copysign(arithmetric1 magni, arithmetric2 sign);
    // value からみて dest の方向にある、 value の次に表現可能な値を取得する。
    float nextafter(float value, float dest);
    double nextafter(double value, double dest);
    long double nextafter(long double value, long double dest);
    arithmetric nextafter(arithmetric1 value, arithmetric2 dest);
    // value からみて dest の方向にある、 value の次に表現可能な値を取得する。
    // 第2引数の型が long double 固定になったこと以外は nextafter と同じ。
    float nexttoward(float value, long double dest);
    double nexttoward(double value, long double dest);
    long double nexttoward(long double value, long double dest);
    double nexttoward(integral value, long double dest);
    // (x - y) と 0 のうち大きい方の値を返す。
    float fdim(float x, float y);
    double fdim(double x, double y);
    long double fdim(long double x, long double y);
    arithmetric fdim(arithmetric1 x, arithmetric2 y);
    // x と y のうち大きい方の値を返す。
    float fmax(float x, float y);
    double fmax(double x, double y);
    long double fmax(long double x, long double y);
    arithmetric fmax(arithmetric1 x, arithmetric2 y);
    // x と y のうち小さい方の値を返す。
    float fmin(float x, float y);
    double fmin(double x, double y);
    long double fmin(long double x, long double y);
    arithmetric fmin(arithmetric1 x, arithmetric2 y);
    // (x * y + z) の計算結果を途中の丸め処理なしで算出する。
    float fma(float x, float y, float z);
    double fma(double x, double y, double z);
    long double fma(long double x, long double y, long double z);
    arithmetric fma(arithmetric1 x, arithmetric2 y, arithmetric3 z);
    // value をカテゴライズした値を返す。
    // value が非数値(NaN)ならば FP_NAN を返す。
    // value が正負の無限大ならば FP_INFINITE を返す。
    // value が 0 ならば FP_ZERO を返す。
    // value が正規化数ならば FP_NORMAL を返す。
    // value が非正規化数ならば FP_SUBNORMAL を返す。
    int fpclassify(float value);
    int fpclassify(double value);
    int fpclassify(long double value);
    // value が有限数であるか否かを調べる。
    bool isfinite(float value);
    bool isfinite(double value);
    bool isfinite(long double value);
    // value が正負の無限大であるか否かを調べる。
    bool isinf(float value);
    bool isinf(double value);
    bool isinf(long double value);
    // value が非数値(NaN)であるか否かを調べる。
    bool isnan(float value);
    bool isnan(double value);
    bool isnan(long double value);
    // value が正規化数であるか否かを調べる。
    bool isnormal(float value);
    bool isnormal(double value);
    bool isnormal(long double value);
    // value にマイナス符号が付いているか否かを調べる。
    bool signbit(float value);
    bool signbit(double value);
    bool signbit(long double value);
    // (value1 > value2) の結果を取得する。
    // 引数のいずれかが非数値であっても FE_INVALID エラーをセットしない。
    bool isgreater(float value1, float value2);
    bool isgreater(double value1, double value2);
    bool isgreater(long double value1, long double value2);
    // (value1 >= value2) の結果を取得する。
    // 引数のいずれかが非数値であっても FE_INVALID エラーをセットしない。
    bool isgreaterequal(float value1, float value2);
    bool isgreaterequal(double value1, double value2);
    bool isgreaterequal(long double value1, long double value2);
    // (value1 < value2) の結果を取得する。
    // 引数のいずれかが非数値であっても FE_INVALID エラーをセットしない。
    bool isless(float value1, float value2);
    bool isless(double value1, double value2);
    bool isless(long double value1, long double value2);
    // (value1 <= value2) の結果を取得する。
    // 引数のいずれかが非数値であっても FE_INVALID エラーをセットしない。
    bool islessequal(float value1, float value2);
    bool islessequal(double value1, double value2);
    bool islessequal(long double value1, long double value2);
    // (value1 < value2 || value1 > value2) の結果を取得する。
    // 引数のいずれかが非数値であっても FE_INVALID エラーをセットしない。
    bool islessgreater(float value1, float value2);
    bool islessgreater(double value1, double value2);
    bool islessgreater(long double value1, long double value2);
    // (isnan(value1) || isnan(value2)) の結果を取得する。
    bool isunordered(float value1, float value2);
    bool isunordered(double value1, double value2);
    bool isunordered(long double value1, long double value2);
  • 下記のマクロ定数が定義された。

    • INFINITY
    • NAN
    • HUGE_VALF
    • HUGE_VALL
    • FP_INFINITE
    • FP_NAN
    • FP_NORMAL
    • FP_SUBNORMAL
    • FP_ZERO
    • FP_FAST_FMA
    • FP_FAST_FMAF
    • FP_FAST_FMAL
    • FP_ILOGB0
    • FP_ILOGBNAN
    • MATH_ERRNO
    • MATH_ERREXCEPT
    • math_errhandling
  • 下記の関数オーバロードが定義された。

    double cos(integral value);
    double sin(integral value);
    double tan(integral value);
    double acos(integral value);
    double asin(integral value);
    double atan(integral value);
    arithmetric atan2(arithmetric1 y, arithmetric2 x);
    double cosh(integral value);
    double sinh(integral value);
    double tanh(integral value);
    double exp(integral value);
    double frexp(integral value, int* e);
    double ldexp(integral value, int e);
    double log(integral value);
    double log10(integral value);
    double modf(integral value, double* intpart);
    double sqrt(integral value);
    double ceil(integral value);
    double floor(integral value);
    arithmetric fmod(arithmetric1 numer, arithmetric2 denom);
    double fabs(integral value);
    double abs(integral value);
  • フリー関数 pow の一部オーバロードが削除され、新しいオーバロードが定義された。

    // C++03
    double pow(double base, int expo);
    long double pow(long double base, int expo);
    // C++11
    arithmetric pow(arithmetric1 base, arithmetric2 expo);

<csetjmp>

変更点なし。

<csignal>

変更点なし。

<cstdarg>

  • 下記のマクロ関数が定義された。

    // 可変長引数リスト src を dest へコピーする。
    void va_copy(va_list dest, va_list src);

<cstddef>

  • 下記の型が定義された。

    max_align_t
    処理系がサポートする最大のアラインメントを持つ型。
    nullptr_t
    nullptr のみを値として持つ型。
  • マクロ定数 NULL の値として 00L の代わりに nullptr を定義することが許容された。

<cstdio>

  • 下記の関数が定義された。

    // 最大許容文字数 length を指定可能になった sprintf 。
    int snprintf(char* dest, size_t length, const char* format, ...);
    // 最大許容文字数 length を指定可能になった vsprintf 。
    int vsnprintf(char* dest, size_t length, const char* format, va_list arg);
    // 設定先が可変長引数から arg になった以外は scanf と同じ。
    int vscanf(const char* format, va_list arg);
    // 設定先が可変長引数から arg になった以外は fscanf と同じ。
    int vfscanf(FILE* fp, const char* format, va_list arg);
    // 設定先が可変長引数から arg になった以外は sscanf と同じ。
    int vsscanf(const char* src, const char* format, va_list arg);

<cstdlib>

  • lldiv_t 構造体が定義された。

    typedef struct
    {
        long long quot;
        long long rem;
    }
    lldiv_t;
  • 下記の関数が定義された。

    // 文字列 src を long long 値に変換する。
    long long atoll(const char* src);
    // 文字列 src の先頭部分の実数文字列を float 値に変換する。
    // 変換の終端位置を end に設定する。
    float strtof(const char* src, char** end);
    // 文字列 src の先頭部分の実数文字列を long double 値に変換する。
    // 変換の終端位置を end に設定する。
    long double strtold(const char* src, char** end);
    // 文字列 src の先頭部分の整数文字列を基数 base で long long 値に変換する。
    // 変換の終端位置を end に設定する。
    long long strtoll(const char* src, char** end, int base);
    // 文字列 src の先頭部分の整数文字列を基数 base で unsigned long long 値に変換する。
    // 変換の終端位置を end に設定する。
    unsigned long long strtoull(const char* src, char** end, int base);
    // quick_exit 関数呼び出し時のコールバックを登録する。
    extern "C" int at_quick_exit(void (*func)(void)) noexcept;
    extern "C++" int at_quick_exit(void (*func)(void)) noexcept;
    // プログラムを速やかに終了させる。
    [[noreturn]] void quick_exit(int status) noexcept;
    // プログラムを終了させる。
    // atexit や at_quick_exit で登録したコールバックは呼び出されない。
    [[noreturn]] void _Exit(int status) noexcept;
    // value の絶対値を算出する。
    long long llabs(long long value);
    // (numer / denum) の商と剰余を算出する。
    lldiv_t lldiv(long long numer, long long denom);
  • 下記の関数オーバロードが定義された。

    long long abs(long long value);
    lldiv_t div(long long numer, long long denom);
  • 下記の関数に条件式なしの noexcept 指定が付与され、例外を投げないことが保証された。

    • abort
    • atexit
  • 下記の関数に [[noreturn]] 属性が指定された。

    • abort
    • exit

<cstring>

変更点なし。

<ctime>

  • 関数 strftime のフォーマット文字列で利用可能な指定子が追加された。

    • %C %D %e %F %g %G %h %n %r %R %t %T %u %V %z
    • %Ec %EC %Ex %EX %Ey %EY
    • %Od %Oe %OH %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy
  • マクロ定数 CLOCKS_PER_SEC の型の定義が変更された。

    • C++03:処理系依存の型。
    • C++11: clock_t 型として評価される型。

<cwchar>

  • 下記の関数が定義された。

    // 設定先が可変長引数から arg になった以外は swprintf と同じ。
    int vswprintf(wchar_t* dest, size_t length, const wchar_t* format, va_list arg);
    // 設定先が可変長引数から arg になった以外は wscanf と同じ。
    int vwscanf(const wchar_t* format, va_list arg);
    // 設定先が可変長引数から arg になった以外は fwscanf と同じ。
    int vfwscanf(FILE* fp, const wchar_t* format, va_list arg);
    // 設定先が可変長引数から arg になった以外は swscanf と同じ。
    int vswscanf(const wchar_t* src, const wchar_t* format, va_list arg);
    // 文字列 src の先頭部分の実数文字列を float 値に変換する。
    // 変換の終端位置を end に設定する。
    float wcstof(const wchar_t* src, wchar_t** end);
    // 文字列 src の先頭部分の実数文字列を long double 値に変換する。
    // 変換の終端位置を end に設定する。
    long double wcstold(const wchar_t* src, wchar_t** end);
    // 文字列 src の先頭部分の整数文字列を基数 base で long long 値に変換する。
    // 変換の終端位置を end に設定する。
    long long wcstoll(const wchar_t* src, wchar_t** end, int base);
    // 文字列 src の先頭部分の整数文字列を基数 base で unsigned long long 値に変換する。
    // 変換の終端位置を end に設定する。
    unsigned long long wcstoull(const wchar_t* src, wchar_t** end, int base);
  • 関数 wcsftime のフォーマット文字列で利用可能な指定子が追加された。
    内容は strftime<ctime>)の変更点と同じ。

<cwctype>

  • 下記の関数が追加された。

    // ワイド文字 c が空白文字ならば 0 以外の値を返す。そうでなければ 0 を返す。
    int iswblank(wint_t c);