| |||
| Home > The C and C++ Libraries > ISO implementation definition > ISO C library implementation definition | |||
The ISO specification leaves some features to the implementors, but requires that implementation choices be documented. This section describes the ARM library implementation.
In the generic ARM C library:
The
macro NULL expands to the integer constant 0.
If a program redefines a reserved external identifier, an error might occur when the program is linked with the standard libraries. If it is not linked with standard libraries, no error is diagnosed.
The __aeabi_assert() function
prints information on the failing diagnostic on stderr and
then calls the abort() function:
*** assertion failed:expression, filename, linenumber
The behavior of the assert macro depends
on the conditions in operation at the most recent occurrence of #include
<assert.h>. See Exiting from an assert for more information.
The following functions test for character values in the range EOF (-1)
to 255 (inclusive):
isalnum()
isalpha()
iscntrl()
islower()
isprint()
isupper()
ispunct().
The ISO C library variants are listed in Library naming conventions.
Table 2.12 shows the default response of mathematical functions when supplied with out-of-range arguments.
Table 2.12. Mathematical functions
| Function | Condition | Returned value | Error number |
|---|---|---|---|
acos(x) | abs(x) > 1 | QNaN | EDOM |
asin(x) | abs(x) > 1 | QNaN | EDOM |
atan2(x,y) | x =0, y = 0 | QNaN | EDOM |
atan2(x,y) | x = Inf, y = Inf | QNaN | EDOM |
cos(x) | x=Inf | QNaN | EDOM |
cosh(x) | Overflow | +Inf | ERANGE |
exp(x) | Overflow | +Inf | ERANGE |
exp(x) | Underflow | +0 | ERANGE |
fmod(x,y) | x=Inf | QNaN | EDOM |
fmod(x,y) | y = 0 | QNaN | EDOM |
log(x) | x < 0 | QNaN | EDOM |
log(x) | x = 0 | -Inf | EDOM |
log10(x) | x < 0 | QNaN | EDOM |
log10(x) | x = 0 | -Inf | EDOM |
pow(x,y) | Overflow | +Inf | ERANGE |
pow(x,y) | Underflow | 0 | ERANGE |
pow(x,y) | x=0 or x=Inf, y=0 | +1 | EDOM |
pow(x,y) | x=+0, y<0 | -Inf | EDOM |
pow(x,y) | x=-0, y<0 and y integer | -Inf | EDOM |
pow(x,y) | x= -0, y<0 and y non-integer | QNaN | EDOM |
pow(x,y) | x<0, y non-integer | QNaN | EDOM |
pow(x,y) | x=1, y=Inf | QNaN | EDOM |
sqrt(x) | x < 0 | QNaN | EDOM |
sin(x) | x=Inf | QNaN | EDOM |
sinh(x) | Overflow | +Inf | ERANGE |
tan(x) | x=Inf | QNaN | EDOM |
atan(x) | SNaN | SNaN | None |
ceil(x) | SNaN | SNaN | None |
floor(x) | SNaN | SNaN | None |
frexp(x) | SNaN | SNaN | None |
ldexp(x) | SNaN | SNaN | None |
modf(x) | SNaN | SNaN | None |
tanh(x) | SNaN | SNaN | None |
HUGE_VAL is an alias for Inf.
Consult the errno variable for the error number.
Other than the cases shown in Table 2.12, all functions return QNaN when
passed QNaN and throw an invalid operation exception
when passed SNaN.
The string passed to C99 nan() is ignored,
and the same Not a Number (NaN) is returned always,
namely the one with all fraction bits clear except the topmost one.
The sign bit is clear as well. Passing strings of the form NAN(xxxx) to strtod has
the same effect.
To enable C99 mathlib error-handling behavior that complies
with POSIX and Annex F of the C99 standard, refer to the symbol __use_c99_matherr in
your program by inserting:
IMPORT __use_c99_matherr, in assembly language
#pragma IMPORT __use_c99_matherr,
in C.
When __use_c99_matherr is defined, the
following behavior applies:
In addition
to setting errno, mathlib functions report errors
by setting IEEE floating-point exception flags. IEEE floating-point
exception flags can only be used in floating-point modes that support
exceptions.
Underflow and overflow range errors, in addition
to setting ERANGE, also set the IEEE overflow
or underflow flag as appropriate (in floating-point modes that support
IEEE exceptions). The underflow flag is also set for partial underflow, that
is, denormal return values, whereas ERANGE is
only set in the case of total underflow (returning zero when the
real mathematical answer is nonzero).
Range errors, in addition to setting ERANGE,
also set either the IEEE invalid operation flag or divide-by-zero
flag, depending on the nature of the range error. Range errors
that set divide-by-zero are:
atanh of -1 and +1
lgamma of zero and of negative integers
log of zero (and equivalently, log10(0), log2(0), and log1p(-1), but not log of negative numbers)
pow(0, negative number)
tgamma(0), but not tgamma of negative numbers.
In legacy RVCT 4.0 behavior, these errors are classed as domain errors rather than range errors.
All other range errors report Invalid Operation.
The IEEE invalid operation flag or divide-by-zero flag is only set in floating-point modes that support IEEE exceptions.
Functions with two input parameters ignore a quiet
NaN in one input parameter if the other input parameter is sufficient
to completely correct the output value. (When __use_c99_matherr is
not defined, a QNaN result is returned if any NaN is present in
the input parameters.) The list of cases that this applies to is
as follows:
hypot(infinity, x) and
hypot(x, infinity) return infinity, even when is QNaNx
pow(x,0) and pow(1,x) return 1, even when is
QNan.x
However, signalling NaNs (unspecified in C99) in these situations still cause an exception and a QNaN return value.
pow(x,0) and pow(1,x) return 1 with no error, for
all finite or infinite value of . (When x__use_c99_matherr is
not defined, pow(infinity,0), pow(1,infinity) and pow(0,0) are domain
errors.
When is
negative and pow(x,y) is infinite in magnitude but has mathematically indeterminate
sign, positive infinity is returned. (When x __use_c99_matherr is
not defined, NaN is returned.) The affected cases are:
pow(-0,fraction)
pow(-0,-infinity)
pow(negative number, ,infinity)
pow(-infinity, ,+infinity)
pow(.-infinity, ,fraction)
All such cases are still domain errors.
pow(-1,gives infinity) +1 with
no error. (When __use_c99_matherr is not defined, pow(-1,gives
NaN with a domain error.)infinity)
atan2( is
treated as if it were infinity, ,infinity)atan2(1,1), with the
same signs, so it returns , pi/43*pi/4, -pi/4,
or -3*. (When pi/4__use_c99_matherr is
not defined, these are domain errors.)
atan2(0,0) is treated as if
it were atan2(0,1), with the same signs, so
it returns +0, -0, ,
or +pi-. (When pi__use_c99_matherr is
not defined, these are domain errors.)
tgamma(0) returns an infinity
of the same sign as the input. (When __use_c99_matherr is
not defined, tgamma(0) returns NaN.) It remains
a domain error.
Table 2.13 shows
the signals supported by the signal() function.
Table 2.13. Signal functions
| Signal | Number | Description | Additional argument |
|---|---|---|---|
| SIGABRT | 1 | This signal is only used if abort() or assert() are called
by your application. | None |
| SIGFPE | 2 | Used to signal any arithmetic exception, for example, division by zero. Used by hard and soft floating-point and by integer division. | A set of bits from {FE_EX_INEXACT, FE_EX_UNDERFLOW, FE_EX_OVERFLOW, FE_EX_DIVBYZERO, FE_EX_INVALID, DIVBYZERO} |
| SIGILL | 3 | Illegal instruction. | None |
| SIGINT | 4 | Attention request from user. | None |
| SIGSEGV | 5 | Bad memory access. | None |
| SIGTERM | 6 | Termination request. | None |
| SIGSTAK | 7 | Obsolete. | None |
| SIGRTRED | 8 | Redirection failed on a runtime library input/output stream. | Name of file or device being re-opened to redirect a standard stream |
| SIGRTMEM | 9 | Out of heap space during initialization or after corruption. | Size of failed request |
| SIGUSR1 | 10 | User-defined. | User-defined |
| SIGUSR2 | 11 | User-defined. | User-defined |
| SIGPVFN | 12 | A pure virtual function was called from C++. | - |
| SIGCPPL | 13 | Exception from C++. | - |
| SIGOUTOFHEAP | 14 | Returned by the C++ function ::operator
new when out of heap space. | Size of failed request |
| reserved | 15-31 | Reserved. | Reserved |
| other | > 31 | User-defined. | User-defined |
Although SIGSTAK exists
in signal.h, this signal is no longer generated
by the C library and is considered obsolete.
A signal number greater than SIGUSR2 can
be passed through __raise(), and caught by
the default signal handler, but it cannot be caught by a handler
registered using signal().
signal() returns an error code if you
try to register a handler for a signal number greater than SIGUSR2.
The default handling of all recognized signals is to print
a diagnostic message and call exit(). This
default behavior applies at program startup and until you change
it.
The IEEE 754 standard for floating-point processing states
that the default action to an exception is to proceed without a
trap. A raised exception in floating-point calculations does not,
by default, generate SIGFPE.
You can modify floating-point error handling by tailoring the functions
and definitions in fenv.h. See Tailoring error signaling, error handling, and program exit and Chapter 4 Floating‑point Support for more
information.
For all the signals in Table 2.13, when a signal occurs, if the handler points
to a function, the equivalent of signal(sig, SIG_DFL) is
executed before the call to the handler.
If the SIGILL signal is
received by a handler specified to by the signal() function,
the default handling is reset.
The generic ARM C library has the following input/output characteristics:
The last line of a text stream does not require a terminating newline character.
Space characters written out to a text stream immediately before a newline character do appear when read back in.
No null characters are appended to a binary output stream.
The file position indicator of an append mode stream is initially placed at the end of the file.
A write to a text stream causes the associated file to be truncated beyond the point where the write occurred if this is the behavior of the device category of the file.
If semihosting is used, the maximum number of open files is limited by the available target memory.
A zero-length file exists, that is, where no characters have been written by an output stream.
A file can be opened many times for reading, but only once for writing or updating. A file cannot simultaneously be open for reading on one stream, and open for writing or updating on another.
Local time zones and Daylight Saving Time are not
implemented. The values returned indicate that the information is
not available. For example, the gmtime() function
always returns NULL.
The status returned by exit() is
the same value that was passed to it. For definitions of EXIT_SUCCESS and EXIT_FAILURE,
see the header file stdlib.h. Semihosting,
however, does not pass the status back to the execution environment.
The error messages returned by the strerror() function
are identical to those given by the perror() function.
If the size of area requested is zero, calloc() and realloc() return NULL.
If the size of area requested is zero, malloc() returns
a pointer to a zero-size block.
abort() closes all open files
and deletes all temporary files.
fprintf() prints %p arguments
in lowercase hexadecimal format as if a precision of 8 had been
specified. If the variant form (%#p) is used,
the number is preceded by the character @.
fscanf() treats %p arguments
exactly the same as %x arguments.
fscanf() always treats the
character "-" in a %...[...] argument as a literal character.
ftell(), fsetpos() and fgetpos() set errno to
the value of EDOM on failure.
perror() generates the messages
shown in Table 2.14.
Table 2.14. perror() messages
| Error | Message |
|---|---|
0 | No error (errno = 0) |
EDOM |
|
|
|
|
|
Others |
|
The following characteristics must be specified in an ISO-compliant implementation (these are unspecified in the ARM C library):
the validity of a filename
whether remove() can remove
an open file
the effect of calling the rename() function
when the new name already exists
the effect of calling getenv() (the
default is to return NULL, no value available)
the effect of calling system()
the value returned by clock().