JTC1/SC22/WG14
N713
Document Number: WG14 N713/J11 97-076
C9X Revision Proposal
=====================
Title: Allow implementations to use extended integers
Author: Douglas A. Gwyn
Author Affiliation: United States Army Research Laboratory
Postal Address: 6449 Tauler Ct., Columbia, MD 21045-4530, US
E-mail Address: gwyn@arl.mil
Telephone Number: +1-301-394-2287
Fax Number: +1-410-278-2934
Sponsor: J11
Date: 1997-06-06
Document History: There have been many previous Committee
and e-mail discussions concerning extended integer
types and their possible use in implementing types
defined by standard headers. The consensus seems
to be that <inttypes.h> and possibly <stddef.h>
typedef-names could be associated with integer types
other than the standard types defined in the current
C standard.
In rewriting the specification for <inttypes.h>, I
found it necessary to revisit this issue and devise
a solution for it, which also resolves similar
issues for other integer types defined in standard
headers.
Proposal Category:
__ Editorial change/non-normative contribution
x_ Correction
__ New feature
__ Addition to obsolescent feature list
__ Addition to Future Directions
__ Other (please specify)
Area of Standard Affected:
__ Environment
x_ Language
__ Preprocessor
__ Library
__ Macro/typedef/tag name
__ Function
__ Header
__ Other (please specify) ______________________________
Prior Art: implementations with extended integer types
Target Audience: C implementers requiring more integer types
Related Documents (if any):
Proposal Attached: x_ Yes __ No, but what's your interest?
Abstract: Currently, the C standard (C89) defines integer
types in terms of standard keywords in certain
allowed combinations, and only those combinations.
The inadequacy of this limitation can be seen in the
fact that the Committee has approved the addition of
{long long} (and related combinations) as a new
integer type for the next C standard (C9x). However,
there is no general mechanism for making conforming
extensions as new needs arise, for example 128-bit
integers when a 64-bit representation for {long long}
has already been chosen for compatibility reasons.
There are also problems choosing a suitable integer
type for {prtdiff_t} on some architectures, where for
example the native word size may be 32 bits and an
object may have a size of more than 2^31 bytes, which
would require 33 bits to represent the difference of
two arbitrary byte pointers within the object.
The new standard header {<inttypes.h>} was largely
motivated by the desire to support implementation-
defined extended integer types, but without necessary
changes in the language section of the standard, it
does not achieve this goal. Also, the {ptrdiff_t}
issue cannot be properly addressed without changes to
allow implementations to, at least in controlled
contexts, introduce extended integer types.
This proposal details the changes that I believe are
necessary and sufficient to address these issues
without causing any other problems.
Proposal: The intent is allow implementations to use extended
integer types in standard headers, without granting
strictly conforming programs any license to use them
directly (only through types defined in the standard
headers). This is tricky to get right, due to the
open-ended nature of potential extended types, which
need to be genuine types for use as function arguments
and so forth, interoperate with other integer types,
and have sufficiently well-defined behavior that a
program runs no risk of becoming not strictly
conforming merely because it might use these types.
The nature of these requirements makes it evident that
the solution must be to incorporate these types into
the appropriate parts of the C language itself;
however, if care is not taken, we run the risk of
allowing a strictly conforming program to contain
implementation-specific identifiers, which of course
is not our intent (strict conformance is supposed to
approximate maximal portability). The key to
addressing this latter concern is to limit the names
for extended integers to those identifiers reserved
"for any use" by the implementation in 7.1.3, which
further reserves them only in the context of standard
headers. Finally, if these types are explicitly made
implementation-defined, then a strictly conforming
program may not use them directly, but only through
the types defined in standard headers (which we have
previously agreed need not expand to segments of
strictly-conforming source code).
Subsection and page numbers in this proposal refer to
Draft 8 of the C9x standard; they may need to be
adjusted to track later drafts. Text surrounded by
*asterisks* should be italicized, while text
surrounded by {braces} should be set in Courier font.
Change 6.1.2.5 Types, p. 30, para. [3], from:
There are five *signed integer
types*, designated as {signed char}, {short
int}, {int}, {long int}, and {long long int}.
to:
There are five *standard signed integer
types*, designated as {signed char}, {short
int}, {int}, {long int}, and {long long int}.
There may also be implementation-defined
*extended signed integer types*. The
standard and extended signed integer types
are collectively called just *signed integer
types*.
Note: The above change adds extended types to the
category of "integer types" throughout the standard.
Because the extended types are implementation-defined,
strictly conforming programs cannot directly use them.
Unsigned and general extended integer types fall
naturally out of subsequent existing wording.
Change in 6.2.1.7 Usual arithmetic conversions, p. 49;
immediately after
Otherwise, the integral promotions are
performed on both operands. Then the
following rules are applied:
insert the following new first rule:
If either operand has an extended
integer type, both operands are
converted to an implementation-defined
common integer type.
Note: This allows the common type to differ from both
operand types, which is compatible with the behavior
for some combinations of standard integer types.
Presumably the required implementation definition will
be "reasonable"; we don't want to try to specify the
details ourselves. (Frank Farance and others have
attempted to devise uniform conversion rules for
general integer types. Unfortunately, there are warts
in the conversion rules for standard types which may
affect their interactions with extended types.)
Notice also that there is no need to force extended
integer types shorter than {int} to undergo change
under "integral promotions"; the only real use of that
property is in variable-argument functions, but
strictly conforming use of (ptrdiff_t} etc. will have
to explicitly convert such an argument to some known
standard type anyway and would not be able to rely on
integral promotion always producing type {int}.
Change in 6.5.2 Type specifiers, p. 81, Syntax [1];
after:
{long}
add new line:
*extended-signed-integer-type*
Optionally, but recommended, add new Syntax rule:
*extended-signed-integer-type*:
*identifier*
Corresponding changes should be made in B.2.2, p.352.
Change in 6.5.2 Type specifiers, p. 81, Constraints
[2]; after:
-- {unsigned long long} or
{unsigned long long int}
add two new lines:
-- an identifier reserved for any use
in 7.1.3 that designates an
implementation-defined extended
signed integer type, or the same
identifier preceded by {signed}
-- the same identifier preceded by
{unsigned}
Change in 6.5.2 Type specifiers, p. 82, Forward
references; add to the end of the reference list:
, reserved identifiers (7.1.3)
Note: I regret having these identifiers show up in
the grammar, but it seems to be logically necessary in
order to provide a way for a typedef to invoke an
extended integer type. Since the only way a strictly
conforming program can access one of these identifiers
is via a typedef name defined in a standard header,
which in effect hides the use of a reserved
identifier, no harm is done. *If the Committee
prefers to leave 6.5.2 unchanged, I can go along with
that, although I am concerned that it would allow a
"reasonable reader" to misinterpret our intent.*
The following should be inserted in I.3.5
(Implementation-defined behavior/Integers), p. 417:
-- Conversion rules involving extended integer
types (6.2.1.7)
Note: I see no need to require the reserved
identifiers to be documented, and it is probably best
to allow implementations flexibility in this regard.
Add to the Index on p. 428:
extended integer type, 6.1.2.5, 6.2.1.7, 6.5.2
(6.1.2.5 should be emboldened.)
In the Rationale document, add a new paragraph to
6.1.2.5 Types, just after any discussion of the new
type {long long}:
Even with the addition of {long long}, the
Committee recognized the need to support other
implementation-defined *extended integer
types*. Rather than introducing a standard
parameterized type or introducing detailed
rules for non-standard types, the use of such
extensions in strictly conforming programs has
been limited to types defined in standard
headers such as {<stddef.h>} and
{<inttypes.h>}. To ensure that extended types
interact properly with standard types, they
were explicitly added to the category of
*integer types*. Conforming implementations
may make use of such types in standard headers,
but since extended types are designated by
reserved identifiers, strictly conforming
programs can use them only through typedef
names defined in those headers.