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.
The macro assert is encouraged to display the current function, as specified
by the new preprocessor macro __func__, as part of its diagnostic message.
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, complex, and
complex. Our version of includes 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 .
Our implementation also provides the added header , with the
usual namespace implications.
The function isblank, which matches at least space and tab (plus other
locale-specific blank characters outside the "C" locale), is added with C99.
The new header 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 , with the
usual namespace implications.
C99 requires that all macros defined in 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.
The new header , which supplements the new header ,
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 . Our implementation adds
overloads in C++ for the functions abs and div.
Our implementation also provides the added header , with the
usual namespace implications.
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 as well.
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).
C99 adds the macro va_copy(va_list), to copy a va_list object.
The new header 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 , just for
completeness (much like ciso646).
The new header 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 , with the
usual namespace implications.
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.
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.
The new header declares generic versions of all the functions
declared in and . 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), 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 , with the
usual namespace implications.
C99 adds the functions wcstof, wcstold, wcstoll, wcstoull.
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 and ) 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