mentations treat all representations
as normal values. Likewise, most sign
magnitude and one’s complement
implementations treat negative zero
as normal values. The C Standards
Committee was unable to identify any
current implementations that treated
these representations as trap values, so
this is a potentially unused and obsolete feature of the C standard.
Pointer types. An integer may be
converted to any pointer type. The
result is implementation-defined,
might not be correctly aligned, might
not point to an entity of the referenced
type, and might be a trap representation. The mapping functions for converting pointers to integers and integers to pointers are intended to be
consistent with the addressing structure of the execution environment.
Floating point-types. IEC 605592 requires two kinds of NaNs (not a number): quiet and signaling. The C Standards Committee has adopted only
quiet NaNs. It did not adopt signaling
NaNs because it is believed that their
utility is too limited for the work required to support them.
7
The IEC 60559 floating-point standard specifies quiet and signaling NaNs,
but these terms can be applied to some
non-IEC 60559 implementations as
well. For example, the VAX reserved
operand and the Cray indefinite are
signaling NaNs. In IEC 60559 standard
arithmetic, operations that trigger a signaling NaN argument generally return
a quiet NaN result, provided no trap is
taken. Full support for signaling NaNs
implies restartable traps, such as the optional traps specified in the IEC 60559
floating-point standard. The C standard
supports the primary utility of quiet
NaNs “to handle otherwise intractable
situations, such as providing a default
value for 0.0/0.0,” as stated in IEC 60559.
Other applications of NaNs may
prove useful. Available parts of NaNs
have been used to encode auxiliary
information—for example, about the
origin of the NaN. Signaling NaNs
might be candidates for filling uninitialized storage, and their available
parts could distinguish uninitialized
floating objects. IEC 60559 signaling
NaNs and trap handlers potentially
provide hooks for maintaining diagnostic information or for implementing special arithmetic.
C support for signaling NaNs, or for
auxiliary information that could be encoded in NaNs, is problematic, however. Trap handling varies widely among
implementations. Implementation
mechanisms may trigger, or fail to trigger, signaling NaNs in mysterious ways.
The IEC 60559 floating-point standard
recommends that NaNs propagate,
but it does not require this, and not
all implementations do this. Additionally, the floating-point standard fails to
specify the contents of NaNs through
format conversion. Making signaling
NaNs predictable imposes optimization restrictions that exceed the anticipated benefits. For these reasons, the C
standard neither defines the behavior
of signaling NaNs, nor specifies the interpretation of NaN significands.
The x86 Extended Precision Format
is an 80-bit format first implemented
in the Intel 8087 math coprocessor
and is supported by all processors
based on the x86 design that incorporate a floating-point unit. Pseudo-infinity, pseudo-zero, pseudo-NaN,
unnormal, and pseudo-denormal are
all trap representations.
Itanium CPUs have a NaT (not a
thing) flag for each integer register. The
Na T flag is used to control speculative
execution and may linger in registers
that are not properly initialized before
use. An 8-bit value may have as many as
257 different values: 0–255 and a Na T
value. C99, however, explicitly forbids a
Na T value for an unsigned char. The
Na T flag is not a trap representation in
C, because a trap representation is an
object representation and an object is a
region of data storage in the execution
environment and not a register flag.
8
Instead of classifying the Itanium
Na T flag as a trap representation, the
following language was added to C11
subsection 6. 3. 2. 1 paragraph 2 to ac-
count for the possibility of a Na T flag:
If the lvalue designates an object of
automatic storage duration that could
have been declared with the register
storage class (never had its address
taken), and that object is uninitialized
(not declared with an initializer and no
assignment to it has been performed
prior to use), the behavior is undefined.
This sentence was added to C11 to
support the Itanium NaT flag to give
compiler developers the latitude to
treat applicable uninitialized reads as
Understanding
how and when
an object
is initialized
is necessary
to understand
the behavior
of reading
an uninitialized
object.