@ 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);