J16/02-0012 WG21/N1354 Proposed C99 Library Additions to C++ P.J. Plauger Dinkumware, Ltd. The revised C standard ISO 9899:1999 (a.k.a. C99) makes extensive additions to the Standard C library. The most obvious ones live in six new headers, but the 18 existing headers (15 from C89 and 3 from Amendment 1) also have a host of additions. I summarize here what has been added since the C++ Standard froze (ISO 14882:1998), along with some suggestions for appropriate C++ machinery to accompany the new stuff. For a more complete description, see the Dinkum C99 Library Reference at http://www.dinkumware.com/refxc.html, which closely reflects the material summarized here. Note that Dinkumware has been shipping a combined C99/C++ library for the past year, so all of the proposed C++ additions have been implemented. SUMMARY OF C99 ADDITIONS AND CHANGES Here is a brief summary of all the features added to the library with C99, since C was last amended in 1995. (C++ incorporates C90 plus Amendment 1 by reference.) I've left out all the places where function pointer arguments now have the restrict access qualifier. I've also left out any number of small tweaks to the semantics of individual functions. <assert.h> The macro assert is encouraged to display the current function, as specified by the new preprocessor macro __func__, as part of its diagnostic message. <complex.h> C99 adds the three types float _Complex, double _Complex, and long double _Complex, with Fortran-ish interconversion rules with the existing real types. The header complex.h also regrettably defines the macro complex, as a synonym for the keyword _Complex. Obviously, this definition should not be present in C++. Less obviously, all the added math functions declared in this header should work properly for complex<float>, complex<double>, and complex<long double>. Our version of <complex.h> includes <complex> and ensures that overloads exist for the C++ complex types, for at least the functions acos, acosh, asin, asinh, atan, atanh, and fabs, none of which are declared in <complex>. Our implementation also provides the added header <ccomplex>, with the usual namespace implications. <ctype.h> The function isblank, which matches at least space and tab (plus other locale-specific blank characters outside the "C" locale), is added with C99. <fenv.h> The new header <fenv.h> declares a host of functions for controlling a floating-point processor (FPP), if it happens to look enough like an IEEE-754 (IEC 60559) FPP. It gives programs an added level of control over rounding modes, floating-point traps, etc. that is important to some sophisticated numeric programs. Our implementation also provides the added header <cfenv>, with the usual namespace implications. <float.h> C99 requires that all macros defined in <float.h> be constant expressions. (FLT_ROUNDS still has the added requirement that it be usable in an #if expression.) The header also adds the macros FLT_EVAL_METHOD and DECIMAL_DIG. <inttypes.h> The new header <inttypes.h>, which supplements the new header <stdint.h>, declares several functions for manipulating values of type intmax_t, a synonym for the largest integer type. It also defines a slew of macros that supply the appropriate scan and print conversion specifiers for the integer types defined in <stdint.h>. Our implementation adds overloads in C++ for the functions abs and div. Our implementation also provides the added header <cinttypes>, with the usual namespace implications. <limits.h> C99 adds macros LLONG_MIN, LLONG_MAX, and ULLONG_MAX, for the new long long and unsigned long long types. Our implementation adds the obvious template specializations to <limits> as well. <math.h> C99 adds all sorts of stuff: -- macros FP_FAST_FMA, FP_FAST_FMAF, FP_FAST_FMAL to signal the presence of fused multiply/add -- macros FP_ILOGB0, FP_ILOGBNAN for error returns from function ilogb -- macros FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO for category returns from macro fpclassify -- macros HUGE_VALF, HUGE_VALL to supplement HUGE_VAL -- macros INFINITY, NAN for special floating-point values -- macros MATH_ERRNO, MATH_ERREXCEPT, math_errhandling to describe handling of math errors -- function macros signbit, fpclassify, isfinite, isinf, isnan, isnormal, isgreater, isgreaterequal, isless, islessequal, islessgreater, isunordered to test floating-point values -- types double_t and float_t for tighter control over computational types -- functions acosh, asinh, atanh, cbrt, copysign, erf, erfc, exp2, expm1, fdim, fma, fmax, fmin, hypot, ilogb, lgamma, llrint, llround, log1p, log2, logb, lrint, lround, nan, nearbyint, nextafter, nexttoward, remainder, remquo, rint, round, scalbln, scanbn, tgamma, and trunc, plus float versions (ending in f) and long double versions (ending in l) Our implementation replaces the function macros (signbit, etc.) with inline functions in C++. It also adds overloads for all the new functions, following the same pattern as in the current C++ Standard (acosh(float) and acosh(long double), for example). <stdarg.h> C99 adds the macro va_copy(va_list), to copy a va_list object. <stdbool.h> The new header <stdbool.h> defines the macros bool (as the builtin type _Bool), true, false, and __bool_true_false_are_defined. In C++, all but the last of these macros should be left undefined, of course. Our implementation also provides the added header <cstdbool>, just for completeness (much like ciso646). <stdint.h> The new header <stdint.h> defines a whole slew of types, of the form: [u]int[fast least]{8 16 32 64}_t [u]int{max ptr}_t and another slew of macros, of the form: INT[FAST LEAST]{8 16 32 64}_MIN [U]INT[FAST LEAST]{8 16 32 64}_MAX INT{MAX PTR}_MIN [U]INT{MAX PTR}_MAX {SIG_ATOMIC WCHAR WINT}{_MAX _MIN} SIZE_MAX plus function macros (for converting literals to a known type) of the form: [U]INT{8 16 32 64}_C Our implementation also provides the added header <cstdint>, with the usual namespace implications. <stdio.h> C99 adds the functions snprintf, vfprintf, vprintf, vsnprintf, vprintf, vfscanf, vscanf, and vsscanf. To the print and scan functions, it adds the conversion specifiers a (for hexadecimal floating-point) and F, and the conversion qualifiers hh, h, ll, t, and z (for various integer types). It also defines the text forms of infinity and NaN values. <stdlib.h> C99 adds the type lldiv_t, and the functions atoll, llabs, lldiv, strtof, strtold, strtoll, strtoull, and _Exit. Our implementation adds the obvious overloads to C++ for abs and div. <tgmath.h> The new header <tgmath.h> declares generic versions of all the functions declared in <complex.h> and <math.h>. These follow Fortran-style rules for determining which version of a function to call, based on the argument type. For example, sqrt(2.0) calls sqrt(double), sqrt(2.0F) calls sqrt(float), and sqrt(2) calls sqrt(double). While this requires compiler magic in C, the same rules can be implemented in C++ by the addition of a single template function for each of the overloaded functions. (Note that the call sqrt(2) is ambiguous if the only visible overloads are sqrt(float), sqrt(complex<float>), etc.) Our implementation provides these added template overloads in C++, to ensure that overload resolution is the same in either C or C++. Our implementation also provides the added header <ctgmath>, with the usual namespace implications. <wchar.h> C99 adds the functions wcstof, wcstold, wcstoll, wcstoull. <wctype.h> C99 adds the function iswblank. RECOMMENDATION C++ should incorporate by reference all the library facilities added with C99, except for the macros that conflict in obvious ways, as described above. It should also adopt the added function overloads and macro replacements that we have found to be successful with our implementation. While some features (such as <inttypes> and <stdbool.h>) are of marginal utility in C++, they are no worse than C features already incorporated in Standard C++. Completeness leads to fewer surprises. This proposal also recommends several language features: -- adding long long integers -- adding hexadecimal floating-point literals -- adding compound (and designated) literals -- defining __STDC_VERSION__ as some value greater than 199901L This proposal does NOT recommend: -- adding the keyword _Complex, and builtin complex arithmetic, to C++ -- adding the keyword _Bool, as a synonym for bool, to C++ This proposal makes NO recommendation about: -- adding the keyword restrict, and restriced pointer semantics, to C++ -- adding variable-length arrays to C++ -- adding __func__ and function macros with variable-length argument lists to the preprocessor