@ page 444 line 9775 section limits.h objection [tog-c99-xbd 1] Problem: Change required for alignment with C99 (ref C99 section 5.2.4.2.1) Action: Add after line 9775: {LLONG_MIN} Minimum value of type long long int Maximum acceptable value: -9223372036854775807 {LLONG_MAX} Maximun value of type long long int Minimum acceptable value: +9223372036854775807 {ULLONG_MAX} Maximum value of type unsigned long long int Minimum acceptable value: 18446744073709551615 @ page 264 line 8824 section float.h objection [tog-c99-xbd 2] Problem: Change required for alignment with C99 (ref C99 section 5.2.4.2.2) Action: Add after line 8824: The values of operations with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type. The use of evaluation formats is characterized by the implementation-dependent value of FLT_EVAL_METHOD: -1 indeterminable; 0 evaluate all operations and constants just to the range and precision of the type; 1 evaluate operations and constants of type float and double to the range and precision of the double type, evaluate long double operations and constants to the range and precision of the long double type; 2 evaluate all operations and constants to the range and precision of the long double type. All other negative values for FLT_EVAL_METHOD characterize implementation-dependent behavior. @ page 265 line 8827 section float.h objection [tog-c99-xbd 3] Problem: Change required for alignment with C99 (ref C99 section 5.2.4.2.2) Action: Insert the following into the table starting on line 8827 (after the section ending with LDBL_MANT_DIG): DECIMAL_DIG number of decimal digits, n, such that any 10 floating-point number in the widest supported floating type with pmax radix b digits can be rounded to a floating-point number with n decimal digits and back again without change to the value, [equation from C99 page 25] @ page 249 line 8349 section assert.h objection [tog-c99-xbd 4] Problem: Change required for alignment with C99 (ref C99 section 7.2) Action: Add after line 8349: "The assert macro is redefined according to the current stat of NDEBUG each time is included." @ page 249 line 8362 section complex.h [tog-c99-xbd 5] Problem: Change required for alignment with C99 (ref C99 section 7.3.1-7.3.4) Action: Add the following header after line 8362: NAME complex.h - complex arithmetic SYNOPSIS #include DESCRIPTION The functionality described on this reference page extends the ISO C standard. Applications shall define the appropriate feature test macro (see the System Interfaces volume of IEEE Std. 1003.1-200x, Section 2.2, The Compilation Environment) to enable the visibility of symbols in this header. The header shall define the following constants: complex expands to _Complex. _Complex_I expands to a constant expression of type const float _Complex, with the value of the imaginary unit (that is, a number i such that i**2 = -1). imaginary expands to _Imaginary. _Imaginary_I expands to a constants expression of type const float _Imaginary with the value of the imaginary unit. I expands to either _Imaginary_I or _Complex_I. If _Imaginary_I is not defined, I expands to _Complex_I. The constants imaginary and _Imaginary_I are only defined if the implementation supports imaginary types. A program may undefine and then, perhaps, redefine complex, imaginary and I. The following shall be declared as functions and may also be defined as macros. Function prototypes shall be provided for use with an ISO C standard compiler. double complex cacos(double complex); float complex cacosf(float complex); long double complex cacosl(long douple complex); double complex casin(double complex); float complex casinf(float complex); long double complex casinl(long double complex); double complex catan(double complex); float complex catanf(float complex); long double complex catanl(long double complex); double complex ccos(double complex); float complex ccosf(float complex); long double complex ccosl(long double complex); double complex csin(double complex); float complex csinf(float complex); long double complex csinl(long double complex); double complex ctan(double complex); float complex ctanf(float complex); long double complex ctanl(long double complex); double complex cacosh(double complex); float complex cacoshf(float complex); long double complex cacoshl(long double complex); double complex casinh(double complex); float complex casinhf(float complex); long double complex casinhl(long double complex); double complex catanh(double complex); float complex catanhf(float complex); long double complex catanhl(long double complex); double complex ccosh(double complex); float complex ccoshf(float complex); long double complex ccoshl(long double complex); double complex csinh(double complex); float complex csinhf(float complex); long double complex csinhl(long double complex); double complex catanh(double complex); float complex catanhf(float complex); long double complex catanhl(long double complex); double complex cexp(double complex); float complex cexpf(float complex); long double complex cexpl(long double complex); double complex clog(double complex); float complex clogf(float complex); long double complex clogl(long double complex); double cabs(double complex); float cabsf(float complex); long double cabsl(long double complex); double complex cpow(double complex, double complex); float complex cpowf(float complex, float complex); long double complex cpowl(long double complex, long double complex); double complex csqrt(double complex); float complex csqrtf(float complex); long double complex csqrtl(long double complex); double carg(double complex); float cargf(float complex); long double cargl(long double complex); double cimag(double complex); float cimagf(float complex); long double cimagl(long double complex); double complex conj(double complex); float complex conjf(float complex); long double complex conjl(long double complex); double complex cproj(double complex); float complex cprojf(float complex); long double complex cprojl(long double complex); double creal(double complex); float crealf(float complex); long double creall(long double complex); APPLICATION USAGE Values are interpreted as radians, not degrees. An implementation may set errno but is not required to. Some of the complex arithmetic functions have branch cuts, across which the function is discontinuous. For implementations with a signed zero (including all IEC 60559 implementations), the sign of zero distinguishes one side of a cut from another so the function is continuous (except for format limitations) as the cut is approached from either side. For example, for the square root function, which has a branch cut along the negative real axis, the top of the cut, with imaginary part +0, maps to the positive imaginary axis, and the bottom of the cut, with imaginary part ­0, maps to the negative imaginary axis. Implementations that do not support a signed zero cannot distinguish the sides of branch cuts. These implementations shall map a cut so the function is continuous as the cut is approached coming around the finite endpoint of the cut in a counter clockwise direction. (Branch cuts for the functions specified here have just one finite endpoint.) For example, for the square root function, coming counter clockwise around the finite endpoint of the cut along the negative real axis approaches the cut from above, so the cut maps to the positive imaginary axis. The usual mathematical formulas for complex multiply, divide, and absolute value are problematic because of their treatment of infinities and because of undue overflow and underflow. The CX_LIMITED_RANGE pragma can be used to inform the implementation that (where the state is on) the usual mathematical formulas are acceptable. The pragma can occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another CX_LIMITED_RANGE pragma is encountered, or until the end of the translation unit. When inside a compound statement, the pragma takes effect from its occurrence until another CX_LIMITED_RANGE pragma is encountered (including within a nested compound statement), or until the end of the compound statement; at the end of a compound statement the state for the pragma is restored to its condition just before the compound statement. If this pragma is used in any other context, the behavior is undefined. The default state for the pragma is off. RATIONALE The choice of I instead of i for the imaginary unit concedes to the widespread use of the identifier i for other purposes. The programmer can use a different identifier, say j, for the imaginary unit by following the inclusion of with #undef I #define j _Imaginary_I 35 An I suffix to designate imaginary constants is not required, as multiplication by I provides a sufficiently convenient and more generally useful notation for imaginary terms. The corresponding real type for the imaginary unit is float so that use of I for algorithmic or 40 notational convenience will not result in widening types. On systems with imaginary types, the programmer has the ability to control whether use of the macro I introduces an imaginary type, by explicitly defining I to be _Imaginary_I or _Complex_I. Disallowing imaginary types is useful for some programs intended to run on 45 implementations without support for such types. The macro _Imaginary_I provides a test for whether imaginary types are supported The cis function (cos(x) + I*sin(x)) was considered but rejected because its implementation is easy and straightforward, even though some implementations could compute sine and cosine more efficiently in tandem. FUTURE DIRECTIONS The function names cerf cerfc cexp2 cexpm1 clog10 clog1p clog2 clgamma ctgamma and the same names suffixed with f or l may be added to the declarations in the header. SEE ALSO The System Interfaces volume of IEEE Std. 1003.1-200x, cacos(), casin(), catan(), ccos(), csin(), ctan(), cacosh(), casinh(), catanh(), ccosh(), csinh(), ctanh(), cexp(), clog(), cabs(), cpow(), csqrt(), carg(), cimag(), conj(), cproj(), creal(). CHANGE HISTORY First released in Issue 6. Entry included for alignment with C99. @ page 257 line 6565 section errno.h [tog-c99-xbd 6] Problem: Change required for alignment with C99 (ref C99 section 7.5). Action: Change "All the error numbers apart from [EDOM] and [ERANGE] are extensions to the ISO C standard ..." To "All the error numbers apart from [EDOM], [ERANGE] and [EILSEQ] are extensions to the ISO C standard ..." @ page 252 line 8424 section ctype.h objection [tog-c99-xbd 7] Problem: Change required for alignment with C99 (ref C99 section 7.4.1.3). Action: Add "int isblank(int); @ page 265 line 8792 section fenv.h [tog-c99-xbd 8] Problem: Change required for alignment with C99 (ref C99 section 7.6-7.6.1). Action: Add the following header after line 8792: NAME fenv.h - floating-point environment SYNOPSIS #include DESCRIPTION The functionality described on this reference page extends the ISO C standard. Applications shall define the appropriate feature test macro (see the System Interfaces volume of IEEE Std. 1003.1-200x, Section 2.2, The Compilation Environment) to enable the visibility of symbols in this header. The header shall define the following data types through typedef: fenv_t which represents the entire floating-point environment. The floating-point environment refers collectively to any floating-point status flags and control modes supported by the implementation. fexcept_t represents the floating-point status flags collectively, including any status the implementation associates with the flags. A floating-point status flag is a system variable whose value is set (but never cleared) when a floating-point exception is raised, which occurs as a side effect of exceptional floating-point arithmetic to provide auxiliary information. A floating-point control mode is a system variable whose value may be set by the user to affect the subsequent behavior of floating-point arithmetic. The header shall define the following constants: FE_DIVBYZERO ) These constants are defined if and only if the FE_INEXACT ) implementation supports the floating-point FE_INVALID ) exception by means of the flaoting-point FE_OVERFLOW ) functions fwclearexcept(), fegetexceptflag(), FE_UNDERFLOW ) feraiseexcept(), fesetexceptflag and ) fetestexcept. Each expands to an integer ) constant expression with values such that ) bitwise ORs of all combinations of the ) constants result in distinct values. FE_ALL_EXCEPT is simply the bitwise OR of all floating-point exception constants defined above. FE_DOWNWARD ) These constants are defined is and only if the FE_TONEAREST ) supports getting and setting the represented FE_TOWARDZERO ) rounding direction by means of the fegetround() FE_UPWARD ) and fesetround() functions. Each expands to an ) integer constant expression whose values are ) distinct non-negative vales. FE_DFL_ENV represents the floating-point environment (that is, the one installed at program startup) and has type "pointer to const-qualified fenv_t). It can be used as an argument to functions that manage the floating-point environment. The following shall be declared as functions and may also be defined as macros. Function prototypes shall be provided for use with an ISO C standard compiler. void feclearexcept(int); void fegetexceptflag(fexcept_t, int); void feraiseexcept(int); void fesetexceptflag(const fexcept_t, int); int fetestexcept(int); int fegetround(void); int fesetround(int); void fegetenv(fenv_t); int feholdexcept(fenv_t); void fesetenv(const fenv_t); void feupdateenv(const fenv_t); APPLICATION USAGE This header is designed to support the floating-point exception status flags and directed-rounding control modes required by IEC 60559, and other similar floating-point state information. Also it is designed to facilitate code portability among all systems. Certain programming conventions support the intended model of use for the floating-point environment: * a function call does not alter its caller's floating-point control modes, clear its caller's floating-point status flags, nor depend on the state of its caller's floating-point status flags unless the function is so documented; * a function call is assumed to require default floating-point control modes, unless stated otherwise in the system documentation; * a function call is assumed to have the potential for raising floating-point exceptions, unless stated otherwise in the system documentation. With these conventions, a programmer can safely assume default floating-point control modes (or be unaware of them). The responsibilities associated with accessing the floating-point environment fall on the programmer or program that does so explicitly. Even though the rounding direction macros may expand to constants corresponding to the values of FLT_ROUNDS, they are not required to do so. The FENV_ACCESS pragma provides a means to inform the implementation when a program might access the floating-point environment to test floating-point status flags or run under non-default floating-point control modes. The pragma shall occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another FENV_ACCESS pragma is encountered, or until the end of the translation unit. When inside a compound statement, the pragma takes effect from its occurrence until another FENV_ACCESS pragma is encountered (including within a nested compound statement), or until the end of the compound statement; at the end of a compound statement the state for the pragma is restored to its condition just before the compound statement. If this pragma is used in any other context, the behavior is undefined. If part of a program tests floating-point status flags, sets floating-point control modes, or runs under non-default mode settings, but was translated with the state for the FENV_ACCESS pragma off, the behavior is undefined. The default state (on or off) for the pragma is implementation-dependent. (When execution passes from a part of the program translated with FENV_ACCESS off to a part translated with FENV_ACCESS on, the state of the floating-point status flags is unspecified and the floating-point control modes have their default settings.) For example: #include void f(double x) { #pragma STDC FENV_ACCESS ON void g(double); void h(double); /* ... */ g(x + 1); h(x + 1); /* ... */ } If the function g might depend on status flags set as a side effect of the first x + 1, or if the second x + 1 might depend on control modes set as a side effect of the call to function g, then the program shall contain an appropriately placed invocation of #pragma STDC FENV_ACCESS ON. RATIONALE The floating-point environment as defined here includes only execution-time modes, not the myriad of possible translation-time options that can affect a program's results. Each such option's deviation from the C Standard should be well documented. Dynamic vs. static modes Dynamic modes are potentially problematic because 1. the programmer may have to defend against undesirable mode settings, which imposes intellectual as well as time and space overhead. 2. the translator may not know which mode settings will be in effect or which functions change them at execution time, which inhibits optimization. C9X addresses these problems without changing the dynamic nature of the modes. An alternate approach would have been to present a model of static modes with explicit utterances to the translator about what mode settings would be in effect. This would have avoided any uncertainty due to the global nature of dynamic modes or the dependency on unenforced conventions. However, some essentially dynamic mechanism still would have been needed in order to allow functions to inherit (honor) their caller's modes. The IEC 60559 standard requires dynamic rounding direction modes. For the many architectures that maintain these modes in control registers, implementation of the static model would be more costly. Also, standard C has no facility, other than pragmas, for supporting static modes. An implementation on an architecture that provides only static control of modes, for example through opword encodings, still could support the dynamic model, by generating multiple code streams with tests of a private global variable containing the mode setting. Only modules under an enabling FENV_ACCESS pragma would need such special treatment. Translation An implementation is not required to provide a facility for altering the modes for translation-time arithmetic, or for making exception flags from the translation available to the executing program. The language and library provide facilities to cause floating-point operations to be done at execution time when they can be subjected to varying dynamic modes and their exceptions detected. The need does not seem sufficient to require similar facilities for translation. The fexcept_t type fexcept_t does not have to be an integer type. Its values must be obtained by a call to fegetexceptflag, and cannot be created by logical operations from the exception macros. An implementation might simply implement fexcept_t as an int and use the representations reflected by the exception macros, but isn’t required to: other representations might contain extra information about the exceptions. fexcept_t might be a struct with a member for each exception (that might hold the address of the first or last floating-point instruction that caused that exception). C9X makes no claims about the internals of an fexcept_t, and so the user cannot inspect it. Exception and rounding macros Unsupported macros are not defined in order to assure that their use results in a translation error. A program might explicitly define such macros to allow translation of code (perhaps never executed) containing the macros. An unsupported exception macro should be defined to be 0, for example #ifndef FE_INEXACT #define FE_INEXACT 0 #endif so that a bitwise OR of macros has a reasonable effect. Exceptions In previous drafts of the C Standard , several of the exception functions returned an int indicating whether the excepts argument represented supported exceptions. This facility was deemed unnecessary because excepts & ~FE_ALL_EXCEPT can be used to test invalidity of the excepts argument. Rounding precision The IEC 60559 floating-point standard prescribes rounding precision modes (in addition to the rounding direction modes covered by the functions in this section) as a means for systems whose results are always double or extended to mimic systems that deliver results to narrower formats. An implementation of C can meet this goal in any of the following ways: 1. By supporting the evaluation method indicated by FLT_EVAL_METHOD equal to 0. 2. By providing pragmas or compile options to shorten results by rounding to IEC 60559 single or double precision. 3. By providing functions to dynamically set and get rounding precision modes which shorten results by rounding to IEC 60559 single or double precision. Recommended are functions fesetprec and fegetprec and macros FE_FLTPREC, FE_DBLPREC, and FE_LDBLPREC, analogous to the functions and macros for the rounding direction modes. The C Standard does not include a portable interface for precision control because the IEC 60559 floating-point standard is ambivalent on whether it intends for precision control to be dynamic (like the rounding direction modes) or static. Indeed, some floating-point architectures provide control modes suitable for a dynamic mechanism, and others rely on instructions to deliver single- and double-format results suitable only for a static mechanism. FUTURE DIRECTIONS None. SEE ALSO The System Interfaces volume of IEEE Std. 1003.1-200x, feclearexcept(), fegetexceptflag(), feraiseexcept(), fesetexceptflag(), fetestexcept(), fegetround(), fesetround(), fegetenv(), feholdexcept(), fesetenv(), feupdateenv(). CHANGE HISTORY First released in Issue 6. Entry included for alignment with C99. @ page 277 line 9114 section inttypes.h [tog-c99-xbd 9] Problem: Change required for alignment with C99 (ref C99 section 7.8). Action: Add after line 9114: The header shall include the header and may extend it with additional facilities provided by host implementations. @ page 277 line 9115 section inttypes.h [tog-c99-xbd 10] Problem: Change required for alignment with C99 (ref C99 section 7.8). Action: Add after line 9115: imaxdiv_t Structure type that is the type of the value returned by the imaxdiv() function. @ page 277 line 9134 section inttypes.h [tog-c99-xdb 11] Problem: Change required for alignment with C99 (ref C99 section 7.8). Action: Add after line 9134: If __STDC_FORMAT_MACROS is defined before is included, then the following object-like macros shall be defined. Each expands to a character string literal containing a conversion specifier, possibly modified by a length modifier, suitable for use within the format argument of a formatted input/output function when converting the corresponding integer type. These macro names have the general form of PRI (character string literals for the fprintf and fwprintf family) or SCN (character string literals for the fscanf and fwscanf family), followed by the conversion specifier, followed by a name corresponding to a similar type name in . In these names, N represents the width of the type as described in . For example, PRIdFAST32 can be used in a format string to print the value of an integer of type int_fast32_t. The fprintf macros for signed integers are: PRIdN PRIdLEASTN PRIdFASTN PRIdMAX PRIdPTR PRIiN PRIiLEASTN PRIiFASTN PRIiMAX PRIiPTR The fprintf macros for unsigned integers are: PRIoN PRIoLEASTN PRIoFASTN PRIoMAX PRIoPTR PRIuN PRIuLEASTN PRIuFASTN PRIuMAX PRIuPTR PRIxN PRIxLEASTN PRIxFASTN PRIxMAX PRIxPTR PRIXN PRIXLEASTN PRIXFASTN PRIXMAX PRIXPTR The fscanf macros for signed integers are: SCNdN SCNdLEASTN SCNdFASTN SCNdMAX SCNdPTR SCNiN SCNiLEASTN SCNiFASTN SCNiMAX SCNiPTR The fscanf macros for unsigned integers are: SCNoN SCNoLEASTN SCNoFASTN SCNoMAX SCNoPTR SCNuN SCNuLEASTN SCNuFASTN SCNuMAX SCNuPTR SCNxN SCNxLEASTN SCNxFASTN SCNxMAX SCNxPTR For each type that the implementation provides in , the corresponding fprintf macros shall be defined and the corresponding fscanf macros shall be defined unless the implementation does not have a suitable fscanf length modifier for the type. The following shall be declared as functions and may also be defined as macros. Function prototypes shall be provided for use with an ISO C standard compiler. intmax_t imaxabs(intmax_t); imaxdiv_t imaxdiv(intmax_t, intmax_t); intmax_t strtoimax(const char * restrict, char ** restrict, int); uintmax_t strtoumax(const char * restrict, char ** restrict, int); intmax_t wcstoimax(const wchar_t * restrict, wchar_t ** restrict, int); uintmax_t wcstoumax(const wchar_t * restrict, wchar_t ** restrict, int); EXAMPLE #include #include int main(void) { uintmax_t i = UINTMAX_MAX; // this type always exists wprintf(L"The largest integer value is %020" PRIxMAX "\n", i); return 0; } @ page 277 line 9137 section inttypes.h [tog-c99-xdb 11a] Problem: Change required for alignment with C99 (ref C99 section 7.8). Action: Change "None." To " was derived from the header of the same name found on several existing 64-bit systems. The C Standard Committee debated other methods for specifying integer sizes and other characteristics, but in the end decided to standardize existing practice rather than innovate in this area. C89 specifies that the language should support four signed and unsigned integer data types, char, short, int and long, but places very little requirement on their size other than that int and short be at least 16 bits and long be at least as long as int and not smaller than 32 bits. For 16-bit systems, most implementations assign 8, 16, 16 and 32 bits to char, short, int, and long, respectively. For 32-bit systems, the common practice is to assign 8, 16, 32 and 32 bits to these types. This difference in int size can create some problems for users who migrate from one system to another which assigns different sizes to integer types, because Standard C’s integer promotion rule can produce silent changes unexpectedly. The need for defining an extended integer type increased with the introduction of 64-bit systems. The purpose of is to provide a set of integer types whose definitions are consistent across machines and independent of operating systems and other implementation idiosyncrasies. It defines, via typedef, integer types of various sizes. Implementations are free to typedef them as Standard C integer types or extensions that they support. Consistent use of this header will greatly increase the portability of a user’s program across platforms." @ page 277 line 9140 section inttypes.h [tog-c99-xdb 11b] Problem: Change required for alignment with C99 (ref C99 section 7.8). Action: Change "None." To "Macro names beginning with PRI or SCN followed by any lowercase letter or X may be added to the macros defined in the header." @ page 297 line 9913 section locale.h [tog-c99-xdb 12] Problem: Change required for alignment with C99 (ref C99 section 7.11). Action: Add after line 9913: char int_n_cs_precedes; char int_n_sep_by_space char int_n_sign_posn char int_p_cs_precedes char int_p_sep_by_space char int_p_sign_posn @ page 299 line 9968 section math.h [tog-c99-xdb 13] Problem: Change required for alignment with C99 (ref C99 section 7.12). Action: Add after line 9968: The header shall define the following macros, where real-floating indicates that the argument shall be an expression of real floating type: int fpclassify(real-floating x); int isfinite(real-floating x); int isinf(real-floating x); int isnan(real-floating x); int isnormal(real-floating x); int signbit(real-floating x); int isgreater(real-floating x, real-floating y); int isgreaterequal(real-floating x, real-floating y); int isless(real-floating x, real-floating y); int islessequal(real-floating x, real-floating y); int islessgreater(real-floating x, real-floating y); int isunordered(real-floating x, real-floating y); @ page 299 line 9968 section math.h [tog-c99-xdb 14] Problem: Change required for alignment with C99 (ref C99 section 7.12). Action: Add after line 9968: The header shall include definitions for at least the following types: float_t A floating type at least as wide as float. double_t A floating type at least as wide as double, and at least as wide as float_t. If FLT_EVAL_METHOD equals 0, float_t and double_t shall be float and double, respectively; if FLT_EVAL_METHOD equals 1, they shall both be double; if FLT_EVAL_METHOD equals 2, they shall both be long double; for other values of FLT_EVAL_METHOD, they are otherwise implementation-dependent. @ page 299 line 9988 section math.h [tog-c99-xdb 15] Problem: Change required for alignment with C99 (ref C99 section 7.12). Action: Add after line 9988: HUGE_VALF A positive float constant expression. Used as an error value returned by the mathematics library. HUGE_VALF evaluates to +infinity on systems supporting the IEEE Std. 754: 1985 standard. HUGE_VALD A positive long double constant expression. Used as an error value returned by the mathematics library. HUGE_VALD evaluates to +infinity on systems supporting the IEEE Std. 754: 1985 standard. INFINITY A constant expression of type float representing positive or unsigned infinity, if available; else a positive constant of type float that overflows at translation time. NAN A constant expression of type float representing a quiet NaN. This symbolic constant is only defined if the implementation supports quiet NaNs for the float type. The following macros shall be defined for number classification. They represent the mutually exclusive kinds of floating-point values. They expand to integer constant expressions with distinct values. Additional implementation-dependent floating-point classifications, with macro definitions beginning with FP_ and an uppercase letter, may also be specified by the implementation. FP_INFINITE FP_NAN FP_NORMAL FP_SUBNORMAL FP_ZERO The following macros are optional. If FP_FATS_FMA is defined, it shall indicate that the fma() function generally executes about as fast as, or faster than, a multiply and an add of double operands. FP_FAST_FMA FP_FAST_FMAF FP_FAST_FMAL FP_FAST_FMAF and FP_FAST_FMAL are, respectively, float and long double analogs of FP_FAST_FMA. The following macros shall expand to integer constant expressions whose values are returned by ilogb(x) if x is zero or NaN, respectively. The value of FP_ILOGB0 shall be either INT_MIN or -INT_MAX. The value of FP_ILOGBNAN shall be either INT_MAX or INT_MIN. FP_ILOGB0 FP_ILOGBNAN The following macros shall expand to the integer constants 1 and 2, respectively; MATH_ERRNO MATH_ERREXCEPT The following macro shall expand to an expression that has type int and the value MATH_ERRNO, MATH_ERREXCEPT, or the bitwise OR of both. The value of math_errhandling is constant for the duration of the program. It is unspecified whether math_errhandling is a macro or an identifier with external linkage. If a macro definition is suppressed or a program defines an identifier with the name math_errhandling, the behavior is undefined. If the expression math_errhandling & MATH_ERREXCEPT can be nonzero, the implementation shall define the macros FE_DIVBYZERO, FE_INVALID, and FE_OVERFLOW in . math_errhandling @ page 299-300 line 9991-10035 section math.h [tog-c99-xdb 16] Problem: Change required for alignment with C99 (ref C99 section 7.12). Action: Add the following prototypes to the list on lines 9991-10035: float acosf(float); float acoshf(float); long double acoshl(long double); long double acosl(long double); float asinf(float); float asinhf(float); long double asinhl(long double); long double asinl(long double); float atan2f(float, float); long double atan2l(long double, long double); float atanf(float); float atanhf(float); long double atanhl(long double); long double atanl(long double); double cbrt(double); float cbrtf(float); long double cbrtl(long double); float ceilf(float); long double ceill(long double); double copysign(double, double); float copysignf(float, float); long double copysignl(long double, long double); float cosf(float); float coshf(float); long double coshl(long double); long double cosl(long double); float erfcf(float); long double erfcl(long double); float erff(float); long double erfl(long double); double exp2(double); float exp2f(float); long double exp2l(long double); float expf(float); long double expl(long double); float expm1f(float); long double expm1l(long double); float fabsf(float); long double fabsl(long double); double fdim(double, double); float fdimf(float, float); long double fdiml(long double, long double); float floorf(float); long double floorl(long double); double fma(double, double, double); float fmaf(float, float, float); long double fmal(long double, long double, long double); double fmax(double, double); float fmaxf(float, float); long double fmaxl(long double, long double); double fmin(double, double); float fminf(float, float); long double fminl(long double, long double); float fmodf(float, float); long double fmodl(long double, long double); float frexpf(float value, int *); long double frexpl(long double value, int *); float hypotf(float, float); long double hypotl(long double, long double); int ilogbf(float); int ilogbl(long double); long int lrint(double); long int lrintf(float); long int lrintl(long double); long int lround(double); long int lroundf(float); long int lroundl(long double); float ldexpf(float, int); long double ldexpl(long double, int); float lgammaf(float); long double lgammal(long double); float log10f(float); long double log10l(long double); float log1pf(float); long double log1pl(long double); double log2(double); float log2f(float); long double log2l(long double); float logbf(float); long double logbl(long double); float logf(float); long double logl(long double); long long int llrint(double); long long int llrintf(float); long long int llrintl(long double); long long int llround(double); long long int llroundf(float); long long int llroundl(long double); float modff(float, float *); long double modfl(long double, long double *); double nan(const char *); float nanf(const char *); long double nanl(const char *); double nearbyint(double); float nearbyintf(float); long double nearbyintl(long double); float nextafterf(float, float); long double nextafterl(long double, long double); double nexttoward(double, long double); float nexttowardf(float, long double); long double nexttowardl(long double, long double); float powf(float, float); long double powl(long double, long double); float remainderf(float, float); long double remainderl(long double, long double); double remquo(double, double, int *); float remquof(float, float, int *); long double remquol(long double, long double, int *); float rintf(float); long double rintl(long double); double round(double); float roundf(float); long double roundl(long double); double scalbln(double, long int); float scalblnf(float, long int); long double scalblnl(long double, long int); double scalbn(double, int); float scalbnf(float, int); long double scalbnl(long double, int); float sinf(float); float sinhf(float); long double sinhl(long double); long double sinl(long double); float sqrtf(float); long double sqrtl(long double); float tanf(float); float tanhf(float); long double tanhl(long double); long double tanl(long double); double tgamma(double); float tgammaf(float); long double tgammal(long double); double trunc(double); float truncf(float); long double truncl(long double); @ page 300 line 10041 section math.h [tog-c99-xdb 17] Problem: Change required for alignment with C99 (ref C99 section 7.12). Action: Change line 10041 to: The FP_CONTRACT pragma can be used to allow (if the state is on) or disallow (if the state is off) the implementation to contract expressions (6.5). Each pragma can occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another FP_CONTRACT pragma is encountered, or until the end of the translation unit. When inside a compound statement, the pragma takes effect from its occurrence until another FP_CONTRACT pragma is encountered (including within a nested compound statement), or until the end of the compound statement; at the end of a compound statement the state for the pragma is restored to its condition just before the compound statement. If this pragma is used in any other context, the behavior is undefined. The default state (on or off) for the pragma is implementation-dependent. @ page 300 line 10042 section math.h [tog-c99-xdb 17a] Problem: Change required for alignment with C99 (ref C99 section 7.12). Action: Change "None." To "Before C9X, the math library was defined only for the floating type double. All the names formed by appending f or l to a name in were reserved to allow for the definition of float and long double libraries; and C9X provides for all three versions of math functions. The functions ecvt, fcvt, and gcvt have been dropped from the C Standard since their capability is available through sprintf. These are provided on XSI-Conformant systems supporting the Legacy Option Group." @ page 324 line 11102 section signal.h [tog-c99-xdb 18] Problem: Change required for alignment with C99 (ref C99 section 7.14). Action: Change "sig_atomic_t Integral type of an object that can be accessed as an atomic entity, ..." To "sig_atomic_t Possibly volatile-qualified integral type of an object that can be accessed as an atomic entity, ..." @ page 344 line 11464 section stdarg.h [tog-c99-xdb 19] Problem: Change required for alignment with C99 (ref C99 section 7.15). Action: Add the following after line 11464: void va_copy(va_list dest, va_list src); @ page 344 line 11478 section stdarg.h [tog-c99-xdb 20] Problem: Change required for alignment with C99 (ref C99 section 7.15). Action: Add the following text after line 11478: The va_copy() macro initializes dest as a copy of src, as if the va_start() macro had been applied to dest followed by the same sequence of uses of the va_arg() macro as had previously been used to reach the present state of src. Neither the va_copy() nor va_start() macro shall be invoked to reinitialize dest without an intervening invocation of the va_end() macro for the same dest. @ page 344 line 11492 section stdarg.h [tog-c99-xdb 21] Problem: Change required for alignment with C99 (ref C99 section 7.15). Action: Change "The va_end( ) macro is used to clean up; it invalidates ap for use (unless va_start( ) is invoked again)." To "The va_end( ) macro is used to clean up; it invalidates ap for use (unless va_start( ) or va_copy() is invoked again). Each invocation of the va_start() and va_copy() macros shall be matched by a corresponding invocation of the va_end() macro in the same function." @ page 345 line 11529 section stdbool.h [tog-c99-xdb 22] Problem: Change required for alignment with C99 (ref C99 section 7.16). Action: Add the following header after line 11529: NAME stdbool.h - boolean type and values SYNOPSIS #include DESCRIPTION The functionality described on this reference page extends the ISO C standard. Applications shall define the appropriate feature test macro (see the System Interfaces volume of IEEE Std. 1003.1-200x, Section 2.2, The Compilation Environment) to enable the visibility of symbols in this header. The header shall define the following macros: bool which expands to _Bool. true which expands to the integer constant 1. false which expands to the integer constant 0. __bool_true_false_are_defined which expands to the integer constant 1. A program may undefine and then possibly redefine the macros bool, true and false. APPLICATION USAGE None. RATIONALE None. FUTURE DIRECTIONS None. SEE ALSO None. CHANGE HISTORY First released in Issue 6. Entry included for alignment with C99. @ page 346 line 11663 section stdint.h [tog-c99-xdb 23] Problem: Change required for alignment with C99 (ref C99 section 7.18). Action: Add the following header after line 11663: NAME stdint.h - integer types SYNOPSIS #include DESCRIPTION The functionality described on this reference page extends the ISO C standard. Applications shall define the appropriate feature test macro (see the System Interfaces volume of IEEE Std. 1003.1-200x, Section 2.2, The Compilation Environment) to enable the visibility of symbols in this header. The header declares sets of integer types having specified widths, and defines corresponding sets of macros. It also defines macros that specify limits of integer types corresponding to types defined in other standard headers. Types are defined in the following categories: — integer types having certain exact widths; — integer types having at least certain specified widths; — fastest integer types having at least certain specified widths; — integer types wide enough to hold pointers to objects; — integer types having greatest width. (Some of these types may denote the same type.) Corresponding macros specify limits of the declared types and construct suitable constants. For each type described herein that the implementation provides, shall declare that typedef name and define the associated macros. Conversely, for each type described herein that the implementation does not provide, shall not declare that typedef name nor shall it define the associated macros. An implementation shall provide those types described as ‘‘required’’, but need not provide any of the others (described as ‘‘optional’’). INTEGER TYPES ============= When typedef names differing only in the absence or presence of the initial u are defined, they shall denote corresponding signed and unsigned types as described in ISO/IEC 9899:1999, section 6.2.5; an implementation providing one of these corresponding types shall also provide the other. In the following descriptions, the symbol N represents an unsigned decimal integer with no leading zeros (e.g., 8 or 24, but not 04 or 048). Exact-width integer types ========================= The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t denotes a signed integer type with a width of exactly 8 bits. The typedef name uintN_t designates an unsigned integer type with width N. Thus, uint24_t denotes an unsigned integer type with a width of exactly 24 bits. These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, it shall define the corresponding typedef names. Minimum-width integer types =========================== The typedef name int_leastN_t designates a signed integer type with a width of at least N, such that no signed integer type with lesser size has at least the specified width. Thus, int_least32_t denotes a signed integer type with a width of at least 32 bits. The typedef name uint_leastN_t designates an unsigned integer type with a width of at least N, such that no unsigned integer type with lesser size has at least the specified width. Thus, uint_least16_t denotes an unsigned integer type with a width of at least 16 bits. The following types are required: int_least8_t uint_least8_t int_least16_t uint_least16_t int_least32_t uint_least32_t int_least64_t uint_least64_t All other types of this form are optional. Fastest minimum-width integer types =================================== Each of the following types designates an integer type that is usually fastest to operate with among all integer types that have at least the specified width. The designated type is not guaranteed to be fastest for all purposes; if the implementation has no clear grounds for choosing one type over another, it will simply pick some integer type satisfying the signedness and width requirements. The typedef name int_fastN_t designates the fastest signed integer type with a width of at least N. The typedef name uint_fastN_t designates the fastest unsigned integer type with a width of at least N. The following types are required: int_fast8_t uint_fast8_t int_fast16_t uint_fast16_t int_fast32_t uint_fast32_t int_fast64_t uint_fast64_t All other types of this form are optional. Integer types capable of holding object pointers ================================================ The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: intptr_t The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: uintptr_t These types are optional. Greatest-width integer types ============================ The following type designates a signed integer type capable of representing any value of any signed integer type: intmax_t The following type designates an unsigned integer type capable of representing any value of any unsigned integer type: uintmax_t These types are required. LIMITS OF SPECIFIED-WIDTH INTEGER TYPES ======================================= The following object-like macros specify the minimum and maximum limits of the types declared in . Each macro name corresponds to a similar type name in section "Integer types". Each instance of any defined macro shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Its implementation-dependent value shall be equal to or greater in magnitude (absolute value) than the corresponding value given below, with the same sign, except where stated to be exactly the given value. Limits of exact-width integer types =================================== * minimum values of exact-width signed integer types INTN_MIN exactly -(2**N-1) * maximum values of exact-width signed integer types INTN_MAX exactly 2**N-1 - 1 * maximum values of exact-width unsigned integer types UINTN_MAX exactly 2**N - 1 Limits of minimum-width integer types ===================================== * minimum values of minimum-width signed integer types INT_LEASTN_MIN -(2**N-1 - 1) * maximum values of minimum-width signed integer types INT_LEASTN_MAX 2**N-1 - 1 * maximum values of minimum-width unsigned integer types UINT_LEASTN_MAX 2**N - 1 Limits of fastest minimum-width integer types ============================================= * minimum values of fastest minimum-width signed integer types INT_FASTN_MIN -(2**N-1 - 1) * maximum values of fastest minimum-width signed integer types INT_FASTN_MAX 2**N-1 - 1 * maximum values of fastest minimum-width unsigned integer types UINT_FASTN_MAX 2**N - 1 Limits of integer types capable of holding object pointers ========================================================== * minimum value of pointer-holding signed integer type INTPTR_MIN -(2**15 - 1) * maximum value of pointer-holding signed integer type INTPTR_MAX 2**15 - 1 * maximum value of pointer-holding unsigned integer type UINTPTR_MAX 2**16 - 1 Limits of greatest-width integer types ====================================== * minimum value of greatest-width signed integer type INTMAX_MIN -(2**63 - 1) * maximum value of greatest-width signed integer type INTMAX_MAX 2**63 - 1 * maximum value of greatest-width unsigned integer type UINTMAX_MAX 2**64 - 1 LIMITS OF OTHER INTEGER TYPES ============================= The following object-like macros specify the minimum and maximum limits of integer types corresponding to types defined in other standard headers. Each instance of these macros shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Its implementation-dependent value shall be equal to or greater in magnitude (absolute value) than the corresponding value given below, with the same sign. * limits of ptrdiff_t PTRDIFF_MIN ­65535 PTRDIFF_MAX +65535 * limits of sig_atomic_t SIG_ATOMIC_MIN see below SIG_ATOMIC_MAX see below * limit of size_t SIZE_MAX 65535 * limits of wchar_t WCHAR_MIN see below WCHAR_MAX see below * limits of wint_t WINT_MIN see below WINT_MAX see below If sig_atomic_t (see ) is defined as a signed integer type, the value of SIG_ATOMIC_MIN shall be no greater than ­127 and the value of SIG_ATOMIC_MAX shall be no less than 127; otherwise, sig_atomic_t is defined as an unsigned integer type, and the value of SIG_ATOMIC_MIN shall be 0 and the value of SIG_ATOMIC_MAX shall be no less than 255. If wchar_t (see ) is defined as a signed integer type, the value of WCHAR_MIN shall be no greater than ­127 and the value of WCHAR_MAX shall be no less than 127; otherwise, wchar_t is defined as an unsigned integer type, and the value of WCHAR_MIN shall be 0 and the value of WCHAR_MAX shall be no less than 255. If wint_t (see ) is defined as a signed integer type, the value of WINT_MIN shall be no greater than ­32767 and the value of WINT_MAX shall be no less than 32767; otherwise, wint_t is defined as an unsigned integer type, and the value of WINT_MIN shall be 0 and the value of WINT_MAX shall be no less than 65535. MACROS FOR INTEGER CONSTANTS ============================ The following function-like macros expand to integer constants suitable for initializing objects that have integer types corresponding to types defined in . Each macro name corresponds to a similar type name in sections "Minimum-width integer types" and "Greatest-width integer types". The argument in any instance of these macros shall be a decimal, octal, or hexadecimal constant with a value that does not exceed the limits for the corresponding type. Macros for minimum-width integer constants ========================================== Each of the following macros expands to an integer constant having the value specified by its argument and a type with at least the specified width. The macro INTN_C(value) shall expand to a signed integer constant with the specified value and type int_leastN_t. The macro UINTN_C(value) shall expand to an unsigned integer constant with the specified value and type uint_leastN_t. For example, if uint_least64_t is a name for the type unsigned long long int, then UINT64_C(0x123) might expand to the integer constant 0x123ULL. Macros for greatest-width integer constants =========================================== The following macro expands to an integer constant having the value specified by its argument and the type intmax_t: INTMAX_C(value) The following macro expands to an integer constant having the value specified by its argument and the type uintmax_t: UINTMAX_C(value) APPLICATION USAGE None. RATIONALE is a subset of more suitable for use in freestanding environments, which might not support the formatted I/O functions. In hosted environments, if the formatted conversion support is not wanted, using this header instead of avoids defining such a large number of macros. FUTURE DIRECTIONS Typedef names beginning with int or uint and ending with _t may be added to the types defined in the header. Macro names beginning with INT or UINT and ending with _MAX, _MIN,or_C may be added to the macros defined in the header. SEE ALSO , , CHANGE HISTORY First released in Issue 6. Entry included for alignment with C99. @ page 348-349 line 11609-111666 section stdio.h [tog-c99-xdb 24] Problem: Change required for alignment with C99 (ref C99 section 7.19). Action: Change the function prototypes on lines 11609-11666 as shown below: Line 11617: int fgetpos(FILE * restrict, fpos_t * restrict); Line 11618: char *fgets(char * restrict, int, FILE * restrict); Line 11621: FILE *fopen(const char * restrict, const char * restrict); Line 11622: int fprintf(FILE * restrict, const char * restrict, ...); Line 11624: int fputs(const char * restrict, FILE * restrict); Line 11625: size_t fread(void * restrict, size_t, size_t, FILE * restrict); Line 11626: FILE *freopen(const char * restrict, const char * restrict, FILE * restrict); Line 11627: int fscanf(FILE * restrict, const char * restrict, ...); Line 11635: size_t fwrite(const void * restrict, size_t, size_t, FILE * restrict); Line 11644: int printf(const char * retsrict, ...); Line 11653: int scanf(const char * restrict, ...); Line 11654: void setbuf(FILE * restrict, char * restrict); Line 11655: int setvbuf(FILE * restrict, char * restrict, int, size_t); Line 11656: int snprintf(char * restrict, size_t, const char * restrict, ...); Line 11657: int sprintf(char * restrict, const char * restrict, ...); Line 11658: int sscanf(const char * restrict, const char * restrict, int ...); Line 11663: int vfprintf(FILE * restrict, const char * restrict, va_list); Line 11664: int vprintf(const char * restrict, va_list); Line 11665: XSI int vsnprintf(char * restrict, size_t, const char * restrict, va_list; Line 11666: int vsprintf(char * restrict, const char * restrict, va_list); And add the following prototypes: int vfscanf(FILE * restrict, const char * restrict, va_list); int vscanf(const char * restrict, va_list); int vsscanf(const char * restrict, const char * restrict, va_list arg); @ page 351 line 11736 section stdlib.h [tog-c99-xdb 25] Problem: Change required for alignment with C99 (ref C99 section 7.20). Action: Add after line 11736: lldiv_t Structure type returned by the lldiv() function. @ page 351-352 line 11752-11813 section stdio.h [tog-c99-xdb 26] Problem: Change required for alignment with C99 (ref C99 section 7.20). Action: Change the function prototypes on lines 11752-11813 as shown below: Line 11782: size_t mbstowcs (wchar_t * restrict, const char * restrict, size_t); Line 11783: int mbtowc (wchar_t * restrict, const char * restrict, size_t); Line 11805: double strtod(const char * restrict, char ** restrict); Line 11806: long int strtol(const char * restrict, char ** restrict, int); Line 11807: unsigned long int strtoul(const char * restrict, char ** restrict, int); Line 11812: size_t wcstombs(char * restrict, const wchar_t * restrict, size_t); And add the following prototypes: void _Exit(int); long long int atoll(const char *); long long int llabs(long long int); ldiv_t ldiv(long int, long int); float strtof(const char * restrict, char ** restrict); long double strtold(const char * restrict, char ** restrict); long long int strtoll(const char * restrict, char ** restrict, int); long long int strtoull(const char * restrict, char ** restrict, int); @ page 355 line 11882-11906 section string.h [tog-c99-xdb 27] Problem: Change required for alignment with C99 (ref C99 section 7.21). Action: Change the function prototypes on lines 11882-11906 as shown below: Line 11885: void *memcpy(void * restrict, const void * restrict, size_t); Line 11888: char *strcat(char * restrict, const char * restrict); Line 11892: char *strcpy(char * restrict, const char * restrict); Line 11897::char *strncat(char * restrict, const char * restrict, size_t); Line 11899: char *strncpy(char * restrict, const char * restrict, size_t); Line 11904: char *strtok(char * restrict, const char * restrict); Line 11906: size_t strxfrm(char * restrict, const char * restrict, size_t); @ page 410 line 13633 section tgmath.h [tog-c99-xdb 28] Problem: Change required for alignment with C99 (ref C99 section 7.22). Action: Add the following entry after line 13633: NAME tgmath.h - type-generic macros SYNOPSIS #include DESCRIPTION The header shall include the headers and and shall define several type-generic macros. Of the and functions without an f (float)orl(long double) suffix, several have one or more parameters whose corresponding real type is double. For each such function, except modf(), there shall be a corresponding type-generic macro. The parameters whose corresponding real type is double in the function synopsis are generic parameters. Use of the macro invokes a function whose corresponding real type and type domain are determined by the arguments for the generic parameters. Use of the macro invokes a function whose generic parameters have the corresponding real type determined as follows: — First, if any argument for generic parameters has type long double, the type determined is long double. — Otherwise, if any argument for generic parameters has type double or is of integer type, the type determined is double. — Otherwise, the type determined is float. For each unsuffixed function in for which there is a function in with the same name except for a c prefix, the corresponding type-generic macro (for both functions) has the same name as the function in . The corresponding type-generic macro for fabs() and cabs() is fabs(). type-generic function function macro -------------------------------------------- acos cacos acos asin casin asin atan catan atan acosh cacosh acosh asinh casinh asinh atanh catanh atanh cos ccos cos sin csin sin tan ctan tan cosh ccosh cosh sinh csinh sinh tanh ctanh tanh exp cexp exp log clog log pow cpow pow sqrt csqrt sqrt fabs cabs fabs If at least one argument for a generic parameter is complex, then use of the macro invokes a complex function; otherwise, use of the macro invokes a real function. For each unsuffixed function in without a c-prefixed counterpart in , the corresponding type-generic macro has the same name as the function. These type-generic macros are: atan2 cbrt ceil copysign erf erfc exp2 expm1 fdim floor fma fmax fmin fmod frexp hypot ilogb ldexp lgamma llrint llround log10 log1p log2 logb lrint lround nearbyint nextafter nexttoward remainder remquo rint round scalbn scalbln tgamma trunc If all arguments for generic parameters are real, then use of the macro invokes a real function; otherwise, use of the macro results in undefined behavior. For each unsuffixed function in that is not a c-prefixed counterpart to a function in , the corresponding type-generic macro has the same name as the function. These type-generic macros are: carg cimag conj cproj creal Use of the macro with any real or complex argument invokes a complex function. APPLICATION USAGE With the declarations: #include int n; float f; double d; long double ld; float complex fc; double complex dc; long double complex ldc; functions invoked by use of type-generic macros are shown in the following table: macro use invokes ----------------------------------- exp(n) exp(n), the function acosh(f) acoshf(f) sin(d) sin(d), the function atan(ld) atanl(ld) log(fc) clogf(fc) sqrt(dc) csqrt(dc) pow(ldc,f) cpowl(ldc, f) remainder(n,n) remainder(n, n), the function nextafter(d,f) nextafter(d, f), the function nexttoward(f,ld) nexttowardf(f, ld) copysign(n,ld) copysignl(n, ld) ceil(fc) undefined behavior rint(dc) undefined behavior fmax(ldc,ld) undefined behavior carg(n) carg(n), the function cproj(f) cprojf(f) creal(d) creal(d), the function cimag(ld) cimagl(ld) cabs(fc) cabsf(fc) carg(dc) carg(dc), the function cproj(ldc) cprojl(ldc) RATIONALE Type-generic macros allow calling a function whose type is determined by the argument type, as is the case for C operators such as + and *. For example, with a type-generic cos macro, the expression cos((float)x) will have type float. This feature enables writing more portably efficient code and alleviates need for awkward casting and suffixing in the process of porting or adjusting precision. Generic math functions are a widely appreciated feature of Fortran. The only arguments that affect the type resolution are the arguments corresponding to the parameters that have type double in the synopsis. Hence the type of a type-generic call to nexttoward, whose second parameter is long double in the synopsis, is determined solely by the type of the first argument. The term type-generic was chosen over the proposed alternatives of intrinsic and overloading. The term is more specific than intrinsic, which already is widely used with a more general meaning, and reflects a closer match to Fortran’s generic functions than to C++ overloading. The macros are placed in their own header in order not to silently break old programs that include , for example with printf("%e", sin(x)). modf(double, double *) is excluded because no way was seen to make it safe without complicating the type resolution. The C Standard differs from an earlier proposal in that the type is determined solely by the argument, and may be narrower than the type for expression evaluation. This change was made because the performance costs for computing functions with narrow arguments to wide range and precision might be too high, even if the implementation efficiently evaluates basic operations to wider format. Also, this differs from earlier proposals in that integer-type arguments are converted to double instead of float. Although converting to float would have been more consistent with the usual arithmetic conversions, converting to double has the advantages of preserving the value more often on many systems, and of being more compatible with C89 where unsuffixed calls to math functions with integer arguments were calls to double functions. Having a g suffix for the generic macros was considered but thought unnecessary. The implementation might, as an extension, endow appropriate ones of the macros that this standard specifies only for real arguments with the ability to invoke the complex functions. The C Standard does not prescribe any particular implementation mechanism for generic macros. It could be implemented simply with built-in macros. The generic macro for sqrt, for example, could be implemented with #undef sqrt #define sqrt(x) _ _BUILTIN_GENERIC_sqrt(x) Generic macros are designed for a useful level of consistency with C++ overloaded math functions. The great majority of existing C programs are expected to be unaffected when is included instead of or . Generic macros are similar to the C89 library masking macros, though the semantic types of return values differ. The ability to overload on integer as well as floating types would have been useful for some functions, for example copysign. Overloading with different numbers of arguments would have allowed reusing names, for example remainder for remquo. However, these facilities would have complicated the specification; and their natural consistent use, such as for a floating abs or a two-argument atan, would have introduced further inconsistencies with C89 for insufficient benefit. The C Standard in no way limits the implementation's options for efficiency, including inlining library functions. FUTURE DIRECTIONS None. SEE ALSO , . CHANGE HISTORY First released in Issue 6. Entry included for alignment with C99. @ page 410 line 13655 section time.h [tog-c99-xdb 29] Problem: Change required for alignment with C99 (ref C99 section 7.23). Action: Change "int tm_sec Seconds [0,61]." To "int tm_sec Seconds [0,60]." @ page 411 line 13720 section time.h [tog-c99-xdb 30] Problem: Change required for alignment with C99 (ref C99 section 7.23). Action: Change "size_t strftime(char *, size_t, const char *, const struct tm *);" To "size_t strftime(char * restrict, size_t, const char * restrict, const struct tm * restrict);" @ page 438-439 line 14752-14826 section wchar.h [tog-c99-xdb 31] Problem: Change required for alignment with C99 (ref C99 section 7.24). Action: Change the function prototypes on lines 14752-14826 as shown below: Line 14753: fwprintf(FILE * restrict, const wchar_t * restrict, ...); Line 14754: int fwscanf(FILE * restrict, const wchar_t * restrict, ...); Line 14768: wchar_t *fgetws(wchar_t * restrict, int, FILE * restrict); Line 14770: int fputws(const wchar_t * restrict, FILE * restrict); Line 14775: size_t mbrlen(const char * restrict, size_t, mbstate_t * restrict); Line 14776: size_t mbrtowc(wchar_t * restrict, const char * restrict, size_t, mbstate_t * restrict); Line 14778: size_t mbsrtowcs(wchar_t * restrict, const char ** restrict, size_t, mbstate_t * restrict); Line 14782: int swprintf(wchar_t * restrict, size_t, const wchar_t * restrict, ...); Line 14783: int swscanf(const wchar_t * restrict, const wchar_t * restrict, ...); Line 14787: int vfwprintf(FILE * restrict, const wchar_t * restrict, va_list); Line 14788: int vwprintf(const wchar_t * restrict, va_list); Line 14789: int vswprintf(wchar_t * restrict, size_t, const wchar_t * restrict, va_list); Line 14791: size_t wcrtomb(char * restrict, wchar_t, mbstate_t * restrict); Line 14792: wchar_t *wcscat(wchar_t * restrict, const wchar_t * restrict); Line 14796: wchar_t *wcscpy(wchar_t * restrict, const wchar_t * restrict); Line 14798: size_t wcsftime(wchar_t * restrict, size_t, const wchar_t * restrict, const struct tm * restrict); Line 14801: wchar_t *wcsncat(wchar_t * restrict, const wchar_t * restrict, size_t); Line 14803: wchar_t *wcsncpy(wchar_t * restrict, const wchar_t * restrict, size_t); Line 14806: size_t wcsrtombs(char * restrict, const wchar_t ** restrict, size_t, mbstate_t * restrict); Line 14809: wchar_t *wcsstr(const wchar_t * restrict, const wchar_t * restrict); Line 14810: double wcstod(const wchar_t * restrict, wchar_t ** restrict); Line 14811: wchar_t *wcstok(wchar_t * restrict, const wchar_t * restrict, wchar_t ** restrict); Line 14812: long int wcstol(const wchar_t * restrict, wchar_t ** restrict, int); Line 14813: unsigned long int wcstoul(const wchar_t * restrict, wchar_t ** restrict, int); Line 14816: size_t wcsxfrm(wchar_t * restrict, const wchar_t * restrict, size_t); Line 14822: wchar_t *wmemcpy(wchar_t * restrict, const wchar_t * restrict, size_t); Line 14825: int wprintf(const wchar_t * restrict, ...); Line 14826: int wscanf(const wchar_t * restrict, ...); And add the following prototypes: int vfwscanf(FILE * restrict, const wchar_t * restrict, va_list); int vswscanf(const wchar_t * restrict, const wchar_t * restrict, va_list); int vwscanf(const wchar_t * restrict, va_list); float wcstof(const wchar_t * restrict, wchar_t ** restrict); long long int wcstoll( const wchar_t * restrict, wchar_t ** restrict, int);" long double wcstold(const wchar_t * restrict, wchar_t ** restrict);" unsigned long long int wcstoull( const wchar_t * restrict, wchar_t ** restrict, int);" @ page 441 line 14880 section wctype.h [tog-c99-xdb 32] Problem: Change required for alignment with C99 (ref C99 section 7.25). Action: Add after line 14880: int iswblank(wint_t);