JTC1/SC22/WG14
N821
Document number: ISO/IEC JTC 1/SC22 WG14 N821
(J11/98-020)
________________ beginning of title page _______________________________
ISO/IEC JTC 1/SC22
Programming languages, their environments and system software interfaces
Secretariat: U.S.A. (ANSI)
ISO/IEC JTC 1/SC22
N2690
TITLE: Summary of Voting on CD Approval of CD 9899 - Information
technology - Programming languages - Programming Language C (Revision of
ISO/IEC 9899:1990)
DATE ASSIGNED:
1998-04-16
SOURCE:
Secretariat, ISO/IEC JTC 1/SC22
BACKWARD POINTER:
N/A
DOCUMENT TYPE:
Summary of Voting
PROJECT NUMBER:
JTC 1.22.20.01
STATUS:
WG14 is requested to prepare a Disposition of Comments Report and a
recommendation on the further processing of the CD.
ACTION IDENTIFIER:
FYI to SC22 Member Bodies
ACT to WG14
DUE DATE:
N/A
DISTRIBUTION:
Text
CROSS REFERENCE:
SC22 N2620
DISTRIBUTION FORM:
Def
Address reply to:
ISO/IEC JTC 1/SC22 Secretariat
William C. Rinehuls
8457 Rushing Creek Court
Springfield, VA 22153 USA
Telephone: +1 (703) 912-9680
Fax: +1 (703) 912-2973
email: rinehuls@access.digex.net
____________ end of title page; beginning of overall summary __________=20
SUMMARY OF VOTING ON
Letter Ballot Reference No: SC22 N2620
Circulated by: JTC 1/SC22
Circulation Date: 1997-12-24
Closing Date: 1998-04-07
SUBJECT: =20
CD Approval of CD 9899: Information technology - Programming languages -
Programming Language C (Revision of ISO/IEC 9899:1990)
----------------------------------------------------------------------
The following responses have been received on the subject of approval:
"P" Members supporting approval
without comment 5
"P" Members supporting approval
with comment 1
"P" Members not supporting approval 4
"P" Members abstaining 2
"P" Members not voting 10
"O" Members supporting approval
without comment 1
------------------------------------------------------------------------
Secretariat Action:
=20
WG14 is requested to prepare a Disposition of Comments Report and make a
recommendation on the further processing of the CD.
The comments accompanying the affirmative vote from Canada and the
negative votes from Denmark, France, Japan and the United Kingdom are
attached. In addition to the comments accompanying the votes from SC22
Member Bodies, Switzerland submitted comments which are also attached for
WG14 consideration.
The comment accompanying the abstention vote from Germany was: "There is
no national rapporteur or committee for C."
________ end of overall summary; beginning of detailed summary ________
ISO/IEC JTC1/SC22 LETTER BALLOT SUMMARY
PROJECT NO: JTC 1.22.20.01
SUBJECT: CD Approval of CD 9899: Information technology - Programming
languages - Programming Language C (Revision of ISO/IEC 9899:1990=
)
=20
Reference Document No: N2620 Ballot Document No: N2620
Circulation Date: 12-24-1997 Closing Date: 04-07-1998=20
=20
Circulated To: SC22 P, O, L Circulated By: Secretariat
SUMMARY OF VOTING AND COMMENTS RECEIVED
Approve Disapprove Abstain Comments Not Voting
'P' Members
Australia ( ) ( ) (X) ( ) ( )
Austria ( ) ( ) ( ) ( ) (X)
Belgium ( ) ( ) ( ) ( ) (X)
Brazil ( ) ( ) ( ) ( ) (X) =20
Canada (X) ( ) ( ) (X) ( )
China ( ) ( ) ( ) ( ) (X)
Czech Republic (X) ( ) ( ) ( ) ( )
Denmark ( ) (X) ( ) (X) ( )
Egypt ( ) ( ) ( ) ( ) (X)
Finland (X) ( ) ( ) ( ) ( )
France ( ) (X) ( ) (X) ( )
Germany ( ) ( ) (X) (X) ( )
Ireland ( ) ( ) ( ) ( ) (X)
Japan ( ) (X) ( ) (X) ( )
Netherlands (X) ( ) ( ) ( ) ( )
Norway (X) ( ) ( ) ( ) ( )
Romania ( ) ( ) ( ) ( ) (X)
Russian Federation ( ) ( ) ( ) ( ) (X)
Slovenia ( ) ( ) ( ) ( ) (X)
UK ( ) (X) ( ) (X) ( )
Ukraine ( ) ( ) ( ) ( ) (X)
USA (X) ( ) ( ) ( ) ( )
'O' Members Voting
Korea Republic (X) ( ) ( ) ( ) ( )
In addition, Switzerland submitted comments.
________ end of detailed summary; beginning of Canada comments ______
Canada Vote on CD Ballot:
Approve with comments
Comments:
Comment #1
Category: Normative
Committee Draft subsection: 6.2.1.2
Title:
Converting to signed integral type
Description:
Section 6.2.1.2 paragraph 3 describes the result of converting a
value with integral type to a signed type which cannot represent
the value. It says that the result is implementation defined,
however, we believe that the result should be undefined, analogous
to the case where an operation yields a value which cannot
be represented by the result type (Section 6.3, paragraph 5).
Comment #2
Category: Normative
Committee Draft subsection: 6.5.6
Title:
VLAs and typedefs
Description:
The draft needs to clearly state when typedefs involving VLAs
get evaluated. The current wording is confusing as it seems to
imply that the size is evaluated at entry to the block instead
of at the start of the scope of the typedef name.
Comment #3
Category: Normative
Committee Draft subsection: 6.5.5.2
Title:
VLAs and side effects
Description:
In section 6.5.5.2, paragraph 3, the draft says, "It is
unspecified whether side effects are produced when the size
expression is evaluated". We believe that the behaviour should
be specified, either that side effects take place or that they
are disallowed and diagnosed at compile time.
Comment #4
Category: Normative
Committee Draft subsection: 7.1.6
Title:
Width of ptrdiff_t
Description:
The width of ptrdiff_t should be required to be at least as
large as the width of size_t.
Comment #5
Category: Normative
Committee Draft subsection: 6.5.4
Title:
Static objects in inline function definitions
Description:
The restriction on static objects defined within an inline
definition of a function with external linkage (section 6.5.4,
paragraph 3) is not sufficient to allow the intended
implementation strategy. Either the restriction should be
corrected (allowing the simple implementation) or dropped
(allowing an implementation to decide whether it can manage to
inline any particular function).
Comment #6
Category: Normative
Committee Draft subsection: 6.5.4
Title:
Linkage of inline definitions
Description:
The interaction between inline and linkage is not clear in the
draft, and the specified syntax for creating an external
function from an inline definition is not in the spirit of C.
Comment #7
Category: Normative
Committee Draft subsection: 7.4.3
Title:
Macros for integer constants
Description:
The macros for integer constants defined in 7.4.3 seem to be
redundant and hard to make robust. Consideration should be
given to eliminating them.
Comment #8
Category: Normative
Committee Draft subsection: 6.3.2.5
Title:
Scope of compound literals
Description:
The last paragraph of 6.3.2.5 (end of example 9, page 79) points
out a highly undesirable property of compound literals: when the
address of a compound literal is taken, correct usage is very
sensitive to the exact placement of braces.
It would seem that the utility of compound literals would not
be greatly reduced if this were simply forbidden; their primary
benefit would appear to be for the creation of compound *values*,
not anonymous variables (C already has a way to create variables,
after all). This restriction would also keep C clear of the
C++ "lifetime of temporaries" swamp.
There is already a C entity which has the desired properties: the
return value of a function. Analogous rules would suffice for
compound literals (and compound literals would fit into the
existing language better that way). Basically, 6.3.2.5 paragraph
5 needs to be modified to delete the last sentence (ie. deny
lvalue status to compound literals), and 6.3.2.5 needs to add a
constraint analogous to 6.7.1 paragraph 3 (ie. type may not be
an array, since there is nothing much that can be done with an
array which doesn't involve taking its address).
____________ end of Canada comments; beginning of Denmark comments ____
Comments on SC22 N2620 CD ballot on C from Danish Standards Association
The Danish vote is "no" with comments.=20
If the following comments can be accomodated, the Danish vote
will be changed to "Yes".
7.3.2 There should only be one expected result for the=20
toupper() and tolower() functions, respectively.
7.5.2.1 int_curr_symbol different from currency_symbol
As there may be differences between the order of how local currency is
written and how international currency is written, it is proposed to=20
add
the following members (none of which are part of the POSIX spec, but
they are part of ISO/IEC FCD 14652) to the lconv struct, as follows:
-------- Start Changed Section ----------
7.5 Localization <locale.h>
[#2]=09...
=09char int_p_cs_precedes; /* CHAR_MAX */
=09char int_p_sep_by_space; /* CHAR_MAX */
=09char int_n_cs_precedes; /* CHAR_MAX */
=09char int_n_sep_by_space; /* CHAR_MAX */
=09char int_p_sign_posn; /* CHAR_MAX */
=09char int_n_sign_posn; /* CHAR_MAX */
-------- End Changed Section ----------
-------- Start Changed Section ----------
7.5.2.1 The localeconv function
[#3] ...
char int_p_cs_precedes=09Set to 1 or 0 if the int_curr_symbol=20
respectively precedes or succeeds the value for a nonnegative formatted
monetary quantity.
char int_p_sep_by_space=09Set to 1 or 0 if the int_curr_symbol respectively
is or is not separated by a space from the value for a nonnegative
formatted monetary quantity.
char int_n_cs_precedes=09Set to 1 or 0 if the int_curr_symbol respectively
precedes or succeeds the value for a negative formatted monetary=20
quantity.
char int_n_sep_by_space=09Set to 1 or 0 if the int_curr_symbol respectively
is or is not separated by a space from the value for a negative=20
formatted monetary quantity.
char int_p_sign_posn=09Set to a value indicating the positioning of the
positive_sign for a nonnegative formatted monetary quantity.
char int_n_sign_posn=09Set to a value indicating the positioning of the
negative_sign for a negative formatted monetary quantity.=20
-------- End Changed Section ----------
In section 7.5.2.1 the examples need to be enhanced.
=09There cannot be a point after ITL.
=09Netherlands use a kind of small "f".
=09Norway have at least a space between "kr" and the value.
We need examples with all the new variables, int_p_cs_precedes etc.
This is all done in the text below.
-------- Start Changed Section ----------
7.5.2.1 The localeconv function
Examples
[#8] The following table illustrates the rules which may well be used=20
by
five countries to format monetary quantities.
Country Positive format Negative format International format
Italy L.1.234 -L.1.234 ITL 1.234
Netherlands f 1.234,56 f -1.234,56 NLG 1.234,56
Norway kr 1.234,56 kr 1.234,56- NOK 1.234,56
Switzerland SFrs.1,234.56 SFrs.1,234.56C CHF 1,234.56
Finland 1.234,56 mk -1.234,56 mk FIM 1.234,56
[#9] For these five countries, the respective values for the monetary=20
members of the structure returned by localeconv are:
Italy Netherlands Norway Switzerland Finland
int_curr_symbol "ITL " "NLG " "NOK " "CHF " "FIM "
currency_symbol "L." "f" "kr" "SFrs." "mk"
mon_decimal_point "" "," "," "." ","
mon_thousands_sep "." "." "." "," "."
mon_grouping "\3" "\3" "\3" "\3" "\3"
positive_sign "" "" "" "" ""
negative_sign "-" "-" "-" "C" "-"
int_frac_digits 0 2 2 2 2
frac_digits 0 2 2 2 2
p_cs_precedes 1 1 1 1 0
p_sep_by_space 0 1 0 0 1
n_cs_precedes 1 1 1 1 0
n_sep_by_space 0 1 0 0 1
p_sign_posn 1 1 1 1 1
n_sign_posn 1 4 2 2 1
int_p_cs_precedes 1 1 1 1 1
int_p_sep_by_space 0 1 0 0 1
int_n_cs_precedes 1 1 1 1 1
int_n_sep_by_space 0 1 0 0 1
int_p_sign_posn 1 1 1 1 1
int_n_sign_posn 1 4 2 2 4
-------- End Changed Section ----------
7.4.2.1 p_sep_by_space and n_sep_by_space
POSIX has added a third possibility for a formatted monetary quantity,=20
so now we have:
=09No space separates the currency_symbol from the value.
=09A space separates the symbol from the value.
*New*=09A space separates the symbol and the value, if these entities are=
=20
next to eachother.
The new parameter is required to properly display monetary amounts
in Denmark and a number of other European countries. For example the
format "DKK -1.234,56" is very common and not doable with the current
C standard.
-------- Start Changed Section ----------
7.5.2.1 The localeconv function
[#3] ...
char p_sep_by_space=09Set to 0 if no space separates the currency_symbol
from the value for a nonnegative formatted monetary quantity; set to 1 if
a space separates the symbol from the value; and set to 2 if a space
separates the symbol and the value, if adjacent.
char n_sep_by_space=09Set to 0 if no space separates the currency_symbol
from the value for a negative formatted monetary quantity; set to 1 if a
space separates the symbol from the value; and set to 2 if a space
separates the symbol and the value, if adjacent.
char int_p_sep_by_space=09Set to 0 if no space separates the int_curr_symbo=
l
from the value for a nonnegative formatted monetary quantity; set to 1 if
a space separates the symbol from the value; and set to 2 if a space
separates the symbol and the value, if adjacent.
char int_n_sep_by_space=09Set to 0 if no space separates the int_curr_symbo=
l
from the value for a negative formatted monetary quantity; set to 1 if a
space separates the symbol from the value; and set to 2 if a space
separates the symbol and the value, if adjacent.
-------- End Changed Section ----------
---------------- added section in rationale -----------------
This section should go into the rationale
A table giving example formats for the combinations of p_cs_precedes,
p_sign_posn and p_sep_by_space is given below, given that the
positive_sign is "+" and the currency_symbol is "$".=20
p_sep_by_space
2 1 0
p_cs_precedes =3D 1 p_sign_posn =3D 0 ($ 1.25) ($ 1.25) ($1.25)
p_sign_posn =3D 1 + $1.25 +$ 1.25 +$1.25
p_sign_posn =3D 2 $1.25 + $ 1.25+ $1.25+
p_sign_posn =3D 3 + $1.25 +$ 1.25 +$1.25
p_sign_posn =3D 4 $ +1.25 $+ 1.25 $+1.25
p_cs_precedes =3D 0 p_sign_posn =3D 0 (1.25 $) (1.25 $) (1.25$)
p_sign_posn =3D 1 +1.25 $ +1.25 $ +1.25$
p_sign_posn =3D 2 1.25$ + 1.25 $+ 1.25$+
p_sign_posn =3D 3 1.25+ $ 1.25 +$ 1.25+$
p_sign_posn =3D 4 1.25$ + 1.25 $+ 1.25$+
------------------------------------------------------------------
7.14.3.5 strftime
The date utility in POSIX-2 4.15 and the strftime() function from
the Open Group Single Unix Specification has all of the formats
of C's strftime() plus more, all of which are proposed to be added to
strftime(), ie merged with the current list:
%C is replaced by the year divided by 100 and truncated to an
integer, as a decimal number (00-99)
%D is replaced by the date in the format mm/dd/yy
%e is replaced by the day of the month as a decimal number (1-31
in a two-digit field with leading <space> fill)
%h a synonym for %b
%n is replaced by a <newline> character
%r is replaced by the 12 h clock time (01-12) using the AM/PM
notation; in the "C" locale, this shall be equivalent to
"%I:%M:%S %p"
%R is replaced by the time in 24 hour notation (%H:%M)
%t is replaced by a <tab> character
A number of modified field descriptors %O<d> and %E<d> are also
defined in POSIX.2 (4.15.4.2) or in The Open Group's strftime()
definition. Text to be added for the C standard,
after the "%%" definition:
Some field descriptors can be modified by the E and O modifier
characters to indicate a different format or specification as
specified in the LC_TIME locale description. If the corresponding
data (see era, era_year, era_d_fmt, and alt_digits) is not specified
or not supported for the current locale, the unmodified field
descriptor value shall be used.
%Ec Locale's alternate date and time representation.
%EC The name of the base year (period) in the locale's alternate
representation.
%Ex Locale's alternate date representation.
%EX Locale's alternate time representation.
%Ey Offset from %EC (year only) in the locale's alternate
representation.
%EY Full alternate year representation.
%Od Day of month using the locale's alternate numeric symbols.
%Oe Day of month using the locale's alternate numeric symbols.
%OH Hour (24-hour clock) using the locale's alternate numeric
symbols.
%OI Hour (12-hour clock) using the locale's alternate numeric
symbols.
%Om Month using the locale's alternate numeric symbols.
%OM Minutes using the locale's alternate numeric symbols.
%OS Seconds using the locale's alternate numeric symbols.
%Ou Weekday using the locale's alternate numeric symbols=20
(Monday=3D1).
%OU Week number of the year (Sunday as the first day of the week)
using the locale's alternate numeric symbols.
%OV Week number using the locale's alternate numeric symbols, using
rules corresponding to %V.
%Ow Weekday as number in the locale's alternate representation
(Sunday=3D0).
%OW Week number of the year (Monday as the first day of the week)
using the locale's alternate numeric symbols.
%Oy Year (offset from %C) in alternate representation.
--------------------------------------------------
Basic addressing of I/O hardware support should be included
in C9X, as I/O addressing support in C is of major importance for=20
the market for free-standing environments.
Denmark believe that having support for I/O addressing in C will be
a great benefit for both the individual programmer, the individual=20
company, and the electronic industry as a whole.
By adding I/O addressing support in C9x as an optional annex, as proposed
in N731, the requirements from the market for free-standing environments =
=20
can be fulfilled, without any inconvenience for those compilers for hosted=
=20
environments which do not want to support I/O addressing.
__________ end of Denmark comments; beginning of France comments ______
From: ARNAUD.A.R.D.DIQUELOU@email.afnor.fr
- N2620 - CD Approval Ballot for CD 9899: C Programming Language
France votes NO to document SC22 N2620. It will reverse its vote if the
following comments are satisfactorily resolved.
General comments:
1. Committee Draft subsections: many
Category: Feature that should be removed (major technical)
Title: Suppression of long long
Rationale:
In C90, the long type had two uses:
- it was the longest integer type available (then by example
its use at the preprocessor level),
- it was the only integer type which warranted 32 bits.
It also had the historical characteristics to be somewhat less
slowly than type int, and to be used to represent offsets in
files (classicaly the integral measure with the greatest
magnitude).
C9X try to extend the standard to permit the writing of programs
handling 64 bits quantities; therefore, this will destroy (at
least) one of the above assertions.
Experience shows that in these cases, one should not extrapolate
from existing features, but rather create a new, heathly mechanism.
This had be done in C9X, and the result is the subclause 7.4 (the
<inttypes.h> header). This clearly distinguish integer types
having a known width from the types named [u]intmax_t, which are
accompanied by functions strtoimax, strtoumax, wcstoimax and
wcstoumax.
Unfortunately, the support for these types, and in particular
[u]intmax_t, is scarse in the rest of the library.
Instead, the proposed draft introduces a solution which have been
implanted in a part of the market: aside from long, there is a new
integer type, long long, which is warrantied to be (at least)
64 bits long; and a number of new library functions to help dealing
with this new type (atoll, llabs, lldiv, llrint, llround, strtoll,
strtoull, wcstoll, wcstoull), and a new "ll" modifier to integer
convertions with *printf and *scanf.
<inttypes.h> correctly does the difference between the (at least)
64 buts long type and the longest type. long long and the
proposed library functions do not, therefore the problem set up
by long (2 signifiances) will not be solved by long long. In fact,
it will lead programers to think long "is" 32 bits and long long
"is" 64 bits... therefore making the very point of <inttypes.h>
useless.
Another defect is that while the historical need for "big" integer
types is with file offsets, there is no long long equivalents for
fseek and ftell. These functions, while superseeded by fsetpos
and fgetpos in some uses, are still necessary (for example when
the program calculate itself the offsets, or when the file have
an externaly defined structure with internal "pointers").
Recommanded changes:
From this analysis, we feel that:
a) long long should be suppressed in the standard, but the door
should be left opened for its use by the mean of the extended
integer types in 6.1.2.5 (note 25 should be modified);
b) direct and indirect obligations to the types described by the
standard should be extended to all the extended integer types
(this include lrint in 7.8, Annex F, and the modification below
to subclause 7.4.4, point #18);
c) [u]intmax_t should be always used when referencing the
longest type (as it is already done in 6.8.2);
d) new functions should be added to <inttypes.h> to do the
equivalent of maxabs, maxdiv, fseekmax, ftellmax, maxrint and
maxround (names are just indications).
Side points:
e) adding atoimax is more problematic, as the atol function is
supposed to be superseeded by strtol.
f) modifier "L" (or "m") could be used to handling integers
of type [u]intmax_t with *printf and *scanf: this is not
necessarily a good idea, as it would also need a modifier
for size_t...)
2. Committee Draft subsections: 5.1.1.2, 5.2.1
Category: Request for information/clarification (major question)
Title: Clarification of the status of UCN
Rationale:
5.1.1.2p1, item 1, and 5.2.1p5 does not make clear if the notation
\Unnnnnnnn consist of either 10 or 1 source character(s). Note 6
in 5.1.1.2 seems to imply it is only 1 character; however notes are
not normative.
If UCN are 10 characters long, there are a number of latent problems
in 5.1.2, 6.1.3.4, 6.1.4, 6.1.7, 6.8.3.2, etc., most of them related
with the special status of the \ character.
We shall assume the correct reading is 1 character.
We shall also assume that UCNs are full-right members of the character
sets (they may need to be clarified in 5.2.1).
There is also a change to be done in 5.1.1.2 to make this clear
(see below, point #4).
Also, a lot of place have not been updated with the appearance of UCNs.
They should be rewritten accordingly (see below for details).
Specific comments:
1. Committee Draft subsections: 4, 7.1, 7.4
Category: Normative change to intent of existing feature (minor
technical)
Title: Making <inttypes.h> available to freestanding implementations
Rationale:
Most of the content of subclause 7.4 (i.e. excluding 7.4.4 and 7.4.6)
should be available for freestanding implementations.
In fact, as those implementations are usualy "closer to the metal",
they may more benefit from these changes like precisely-sized
types than the hosted ones.
However, the whole content of actual subclause 7.4 is not suitable
for freestanding implementations.
Proposed solution:
A way to achieve it is to divide subclause 7.4 into two parts: a
first one, containing the actuals subclauses 7.4 to 7.4.3 and
7.4.5, should be put in a new subclause 7.1.x preceding 7.1.6,
and should be made mandatory to freestanding implementations
(by updating clause 4). It should keep the existing title.
The rest, i.e. 7.4.4 and 7.4.6, should be left as an independant
subclause 7.x (while being moved, depending of the spelling of
the corresponding header); it may be named <stdint.h> (just a
proposal).
For strtoimax() and the like to be usefully used, it might be
necessary to make the declaration of intmax_t also available
in this new header.
2. Committee Draft subsection: 5.1.1.2
Category: Request for information/clarification (minor question)
Title: locale to be used for source characters
What is the locale to be used for the convertion of multi-byte
source characters to UCN and then to execution characters?
Should it be unspecified or implementation-defined?
Or locale-specific (to permit strict conformance)?
A reference in annexe K is also needed.
Rationale:
As it stands now, it is undefined for source characters, thus
forbids any strictly conforming program with characters outer of
the basic character set should be written with \u or \U. Is it
as intended?
3. Committee Draft subsection: 5.1.1.2
Category: Normative change to existing feature retaining the
original intent (minor technical)
Title: Prohibit surrogates to being used as UCNs
Rationale:
5.1.1.2p2 (Contraints) excludes some ranges to be used with UCNs.
The range D000-DFFF (used for UTF-16, these values by themselves, named
"surrogates", do not represent characters) should be excluded as well.
Proposed solution:
Exclude the range D000-DFFF as well.
3. Committee Draft subsection: 5.1.1.2
Category: Editorial change/non-normative contribution (minor editorial)
Title: Consistency with ISO/IEC 10646
Proposed change:
5.1.1.2p2 (Contraints) specifies some range to be not used with UCNs.
The references should be written in full (canonical) form, like 0000 0000=
,
0000 0020, 0000 007F, 0000 009F (and 0000 D000, 0000 DFFF).
4. Committee Draft subsections: 5.1.1.2
Category: Normative change to intent of existing feature (major
technical)
Title: Clarification of the status of UCN
Rationale:
5.1.1.2p1, item 1, and 5.2.1p5 does not make clear if the notation
\Unnnnnnnn consist of either 10 or 1 source character(s). Note 6
in 5.1.1.2 seems to imply it is only 1 character; however notes are
not normative.
Proposed solution:
If "1 character" is the correct reading, then a sentence should be
added to 5.1.1.2 to specify that the sequence of 10 source characters
{\}{U}{n}{n}{n}{n}{n}{n}{n}{n} should be transformed in one character
(during translation phase 1).
5. Committee Draft subsection: 5.2.1
Category: Editorial change/non-normative contribution (minor editorial)
Title: Consistency with ISO/IEC 10646
Proposed change:
In 5.2.1p5, the reference to the Standard should be ISO/IEC 10646,
without specifying the 1st part. This way, one could safely uses
characters outside BMP when they will be defined.
6. Committee Draft subsection: 5.2.1
Category: Inconsistency (minor technical)
Title: Are UCN part of the basic character set?
Rationale:
5.2.1p1, last sentence should written another way. As it stands now,
=09=09=09=09=09=09=09=09=09=09=09=09=09 any additional
members beyond those required by this subclause are locale-
specific.
Given the fact that the UCN notation is described in this very
subclause, and that it includes all the characters in ISO/IEC 10646,
the present writing is somewhat useless. See also below an
implication for 6.8p4.
Proposed change:
Move the UCNs (5.1.2p4-5) to another (new) subclause to highlight the
difference between the basic and the extended character sets.
7. Committee Draft subsection: 5.2.1
Category: Inconsistency (minor editorial)
Title: Clarification of the status of UCN
Proposed change:
In 5.2.1p3, the last sentence should be deleted. It says:
If any other characters are
encountered in a source file (except in a character
constant, a string literal, a header name, a comment, or a
preprocessing token that is never converted to a token), the
behavior is undefined.
Another possibility is to add identifer to the list of items.
8. Committee Draft subsection: 5.2.1.1
Category: Editorial change/non-normative contribution (minor editorial)
Title: Correct designation of a national standard
Rationale:
5.2.1.1, note 12, references "the ASCII code set". In the context of
an International Standard, it should be for example "the US ASCII code
set".
Proposed change:
Add "US".
9. Committee Draft subsection: 5.2.1.2
Category: Inconsistency (minor editorial)
Title: Handling of UCNs into identifiers
Rationale:
In 5.2.1.2p2, in the two first items, "identifier" should be added to
the lists.
They also may be considered now useless, as shift states have been
removed in translation phase 1, and hence all multibyte characters
are valid (or the source will be rejected at translation phase 1).
Proposed changes:
- An identifier, comment, string literal, character constant,
or header name shall begin and end in the initial shift
state.
- An identifier, comment, string literal, character constant,
or header name shall consist of a sequence of valid
multibyte characters.
10. Committee Draft subsection: 5.2.2
Category: Normative change to existing feature retaining the original
intent (minor technical)
Title: Making character display semantics in line with MSE
Rationale:
5.2.2p1, first sentence, describes the `active position' in relation
with fputc:
[#1] The active position is that location on a display
device where the next character output by the fputc function
would appear.
It should be `the fputc or fputwc functions' instead.
Similarly, the next sentence describes a `printable character' as being
defined by isprint:
The intent of writing a printable character
(as defined by the isprint function) to a display device [...]
It should be `as defined by the isprint or iswprint functions' instead.
11. Committee Draft subsections: 6.1.3.4, 6.1.4
Category: Inconsistency (minor technical)
Title: Making string litterals in line with character constants
Rationale:
The rules for the building of wide character constants and
string literals are non consistent.
6.1.3.4p11 says, in part:
The value of a wide
character constant containing a single multibyte character
that maps to a member of the extended execution character
set is the wide character (code) corresponding to that
multibyte character, as defined by the mbtowc function, with
an implementation-defined current locale. The value of a
wide character constant containing more than one multibyte
character, or containing a multibyte character or escape
sequence not represented in the extended execution character
set, is implementation-defined.
On the other hand, 6.1.4p5 says:
for
wide string literals, the array elements have type wchar_t,
and are initialized with the sequence of wide characters
corresponding to the multibyte character sequence.
Proposed solution:
The latter should be reworded to the following:
for
wide string literals, the array elements have type wchar_t,
and are initialized with the sequence of wide characters
corresponding to the multibyte character sequence, as
defined by the mbstowcs function, with an implementation-
defined current locale. The value of a wide string literal
containing multibyte characters or escape sequences not
represented in the extended execution character set, is
implementation-defined.
Also note that if a change is done to 6.1.3.4p11 to include
universal character names in the list of items that may lead to
implementation-defined behavior, the same change should be made
to the proposed text accordingly.
12. Committee Draft subsection: 6.1.7
Category: Inconsistency (minor editorial)
Title: Handling of UCNs into an example
Proposed change:
6.1.7p4, last example, should be
{#}{define} {const}{.}{member}{\U00000040}{\U00000024}
13. Committee Draft subsection: 6.1.9
Category: Inconsistency (minor editorial)
Title: Handling of multibytes during preprocessing
Rationale:
6.1.9p2, last sentence.
There should be no need to examine the comments to find multibytes
characters, as they are replaced by UCN during translation phase 1.
Proposed solution:
Remove the reference to multibytes.
14. Committee Draft subsection: 6.8
Category: Inconsistency (minor editorial)
Title: Are UCN source characters? or escape sequences? or another thing?
Proposed change:
6.8p4, replace
[#4] In the definition of an object-like macro, if the first
character of a replacement list is not a character required
by subclause 5.2.1, then there shall be white-space
separation between the identifier and the replacement
list.122
with
In the definition of an object-like macro, if the first
character of a replacement list is neither a character
required by subclause 5.2.1, nor an universal character name
listed in Annex I, then there shall be white-space separation
between the identifier and the replacement list.{122}
The footnote then remains valid.
Also note that the above modification (#6) must be made, as presently
all UCNs are required by subclause 5.2.1
15. Committee Draft subsection: 6.8.3.3
Category: Inconsistency (minor editorial)
Title: Are UCN source characters? or escape sequences? or another thing?
Proposed change:
6.8.3.3p3, add before last sentence
If the result of the concatenation is syntaxly identical to an
UCN, the behavior is undefined.
This will prevent the following example to be strictly conforming:
#define paste(a,b) a ## b
#define mkstr1(s) #s
#define mkstr(s) mkstr1(s)
char value[] =3D mkstr(paste(\u, 0024));
as it will fool a number of implementations using preprocessors.
16. Committee Draft subsection: 6.8.8
Category: Other: Addition of a new feature (minor technical)
Title: New conditionaly predefined macro name __STDC_ISO_10646__
Rationale:
While C9X adds support for all the universal character names in
identifiers, there is currently no requisite to an implementation
for the extended set of character to represent the whole set
defined in ISO/IEC 10646:1993, and furthermore no conforming way
for a program to learn if the type wchar_t could be used for
this purpose. This point intends to solve this problem.
Proposed solution:
By defining a new constant named __STDC_ISO_10646__, the
implementation will indicate that the values of type wchar_t are
suitable to represent the elements of the universal character
set defined in ISO/IEC 10646; as an example, in this case,
L'A' will be guaranteed to be equal to 0x0041u.
Furthermore, as ISO/IEC 10646 is an evolving standard, the value
of the predefined macro should reflect the level ISO/IEC
implemented, by the same mechanism as used by __STDC_VERSION__,
i.e. by specifiying the year and month of the registration of
the lastly supported amendment (so support of ISO/IEC 10646:1993
up to Am.9, which is the last one issued now, will be showed by
defining the macro as 199712L).
This can be done by adding a new item to the list in 6.8.8p2,
which reads as:
=09 __STDC_ISO_10646__ A decimal constant of the form YyyyMmL
=09 (for example 199712L), intended to indicate that the values
=09 of the type wchar_t (as defined in the <stddef.h> header)
=09 are the coded representations of the characters defined
=09 by ISO/IEC 10646 (Universal Multiple-Octet Coded Character
=09 Set, UCS), to the level specified by this standard with
=09 all amendments applied up to the month "Mm" of the year
=09 "Yyyy".
A better wording can perhaps being found.
Another solution (similar to the one used for floating-point
support) is to include a new normative annex, and to require
in this annex the specifications of Unicode (regarding
classification of characters) and of ISO/IEC FCD 14652
(regarding collation of strings made of UCS characters).
17. Committee Draft subsection: 7.1, 7.17
Category: Editorial change/non-normative contribution (minor editorial)
Title: Moving <iso646.h> to a more logicial position
Rationale:
7.17, Alternative spellings <iso646.h>, is nowadays positionned
after its established position coming from Am.1:1996 to
ISO/IEC 9899:1990, i.e. after the <time.h> subclause.
This is now illogical, as <stdbool.h> (also required for
freestanding implementations) have been put in subclause 7.1,
and as the new header introduced by C9X have been put in
their logical position regarding the alphabetic order (which
is not the case for <iso646.h>).
Proposed solution:
Subclause 7.17 should be moved to a new subclause 7.1.x
before 7.1.6 <stddef.h>.
18. Committee Draft subsection: 7.4.4
Category: Inconsistency (minor technical)
Title: Allow other convertions modifiers to be used in 7.4.4
Rationale:
6.1.2.5 introduces the new concept of "extended integer types", which
can exist beyond char, short, int, long and long long.
Unfortunately, 7.4 specifies that modifiers corresponding to the
defined types should be those described by the standard ("hh", "h",
"l" and "ll") therefore forbiding a implementation to define
the types in <inttypes.h> as one of the extented types.
Proposed solution:
Remove the restriction.
19. Committee Draft subsection: 7.19.7.1.2
Category: Inconsistency (minor technical)
Title: Making positive the non-error return value of wctob
Rationale:
7.19.7.1.2, the wctob function, does not describe the sign convention of
the single-byte representation returned. In particular, 7.19.7.1.2p3 say=
s:
Otherwise, it returns the single-byte representation
of that character.
Proposed solution:
It should be written as
Otherwise, it returns the single-byte representation
of that character, as an unsigned char converted to an int.
(This is copied from the description of fgetc).
Note this is a quiet change from ISO/IEC 9899:1990/Am.1:1996
(existing implementations where char are signed may have
chosen to return negative values; the new behavior can lead
to overflow problems).
______ end of France comments; beginning of Japan comments ________
CD Approval Ballot for CD 9899:
Information technology - Programming languages -=20
Programming Language C (revision of ISO/IEC 9899:1990)
----------------------------------------------------------
The National Body of Japan disapproves ISO/IEC JTC1/SC22 N
2620, "CD Approval Ballot for CD 9899: Information
technology - Programming languages - Programming Language C
(revision of ISO/IEC 9899:1990)" for reasons below.
1. Technical Comments
---------------------
Japan has been having some technical comments which were
submitted to SC22 at the CD registration ballot. WG14 made
the disposion paper (SC22 N2618) for these comments.=20
However, Japan can not agree with some of WG14's
dispositions. Section 3 in this paper describes such a
kind of open issues (including editorial comments). As for
technical issues, please refere subsection 3.1 through 3.3:
- 3.1 The 64 bit data type should be optional
- 3.2 The function atoll() is redundant as the ISO C
language standard
- 3.3 Example of ## operator
1.1 Multibyte characters in source file
@ Subclause "5.1.1.2 Translation phases"
Page 8-9, line 4-6 in paragraph 1:
> Any multibyte source file character not in the basic
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=20
> source character set is replaced by the
> ~~~~~~~~~~~~~~~~~~~~
> universal-character-name that designates that multibyte
> character.
This description reads that *ALL* of conforming
implementations should replace *ANY* MULTIBYTE CHARACTERS IN
THE SOURCE FILE to universal-character-name. If this is
true, we have three questions below:
1) This rule says that any Japanese Kanji Characters in the
source file should be replaced to universal-character-name
by *ANY* implementations EVEN IF THEY ARE MADE IN US. Is
this the intention of SC22/WG14? (We do not think so.)
2) Does the ISO C standard prohibit an implementation from
supporting multibyte character as the source character
set which are NOT defined in the Annex I "Universal
character names for identifiers"? (We do not think
this is SC22/WG14's intention.)
3) This rule says that *ALL* of conforming implementations must
have the conversion table between physical multibyte
characters and a full set of universal-character-name
defined in Annex I. The table must be very big. That is,
the conforming implementation must be very fat. It is
not welcome to users. Is this the intention of
SC22/WG14? (We do not think so.)
So, the above description should be changed to more
precise sentence by using well-defined terms:
> Then, the member of the extended character set of the
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> source which is not in the basic source character set may
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> be replaced by the universal-character-name that
> designates that extended source character set members.
2. Editorial Comments
---------------------
2.1 Multibyte characters in source file
@ Subclause "5.1.1.2 Translation phases"
Page 8, Line 3-5 in paragraph 1:
> 1. Physical source file multibyte characters are mapped to
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> the source character set ... if necessary.
> Any multibyte source file character not in the basic
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> source character set is...
Wording "Physical source file multibyte characters" and
"multibyte source file character" are slightly
unintelligible.=20
> Any source file multibyte character not in the basic
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> source character ...
makes clearer.
2.2 Wrong reference to Annex I
@ Subclause "6.1.2 Identifier"
Page 34, line 4 in paragraph 2:
"Annex H" should be corrcted to "Annex I".
2.3 "Function-sepcifiers" should be "function-specifier"
@ Subclause "6.5 Declarations"
Page 100, line 7 in paragraph 1:
Syntactic category "function-sepcifiers" should be the same
as "function-specifier" which is defined in "6.5.4 Function
specifiers" (Page 116). Threfore, "function-sepcifiers"
should be changed to "function-specifier". Annex B2.2 (page
444) should be corrected similarly.
2.4 "Function-sepcifiers" should be followed by other
syntactic category
@ Subclause "6.5 Declarations"
Page 100, line 7 in paragraph 1:
Syntactic category "function-sepcifiers" is defined
alone. So, the C user cannot write other
"declaration-specifiers" following it. It should be
followed by "declaration-specifiers opt". Annex B2.2 (page
444) should be corrected similarly.=20
2.5 Wrong sentence in Tags
@ Subclause "6.5.2.3 Tags"
Page 108, line 2 in paragraph 3:
"The type is complete" should be corrcted to=20
"The type is incomplete".
2.6 The behavior of "rewrite" should be clarified.
@ Subclause "6.5.5.3 Function declarators(including
prototypes)"
Page 123, line 1 in paragraph 4:
The term "rewrite" in the description:
"After all rewrites, the parameters in a parameter-type-list
that is part of a function definition shall not have
incomplete type."
is not defined anywhere. The behavior of "rewrite" should
be clarified.
2.7 Examples for VLA is needed
@ Subclause "6.5.6 Type names"
Page 127, paragraph 3:
The definitions of variable length array (VLA) are added in
the syntax of the subclause 6.5.6. But any examples of VLA
does not exist. Threfore, the examples of VLA should be
added if possible like subclause 6.5.5.2 and 6.5.5.3.
2.8 "Declaration-list" should be defined
@ Subclause "6.7.1 Function definitions"
Page 150, line 2 in paragraph 1:
In draft 11, "declaration-list" was dropped, because
"block-item-list" was newly defined in "6.6.2 Compound
statement, or block" (page 140) instead of "declaration-list"
and "statement-list". It should be defined in 6.7.1 or
elsewhere. Annex B2.4 (page 448) should be corrected
similarly.
2.9 Publised year of ISO/IEC 9899 mismatches
@ Subclause "6.8.8 Predefined macro names"
Page 171, footnote 128
> 128. The value in ISO/IEC 9899:1994 was 199409L.
@ Annex A "Bibliography" 12.
Page 434
> ISO/IEC 9899:1993, Programming languages -- C
Which is correct?
Please use the correct document name/year.
2.10 Garbage in postscript file
@ Subclause "6.8.8 Predefined macro names"
Pages 171, line 2 in paragraph 2:
> 1912.nr:c 0u+000m'unu
This line looks like an garbage in the post script file of
CD.
Please correct it.
2.11 Missing information from asert macro for the identifire
__func__
@ Subclause "7.2.1.1 The assert macro"
Page 183, line 3-6 in paragraph 2:
The information about the identifire __func__ should be
added to the contents of the information written by asert
macro.
2.12 Unnecessary description of C++ implementations
@ Subclause "7.4.2 Limits of specified-width integer types"
Page 193, footnote 149:
@ Subclause "7.4.3 Macros for integer constants"
Page 195, footnote 150:
@ Subclause "7.4.4 Macros for format specifiers"
Page 196. footnote 151:
What is the intention of using the term "C++ implementations"
in the footnote 149, 150, and 151 ?
They should be removed from the specification of the C
standard.
2.13 Place of reference to the footnote 153
@ Subclause "7.5 Localization <locale.h>"
Page 202, line 1 in paragraph 3:
It seems that the place of the reference to the footnote 153
is wrong (but, Japan is not so convinced whether or not it is
wrong.)
> The macros defined are NULL (described in 7.1.6);
> and 153
+--+-> Is this place right? =20
Please make clear.
2.14 Defintions for float and long double math functions
@ Subclause "7.7 Mathematics <math.h>"
Page 218, paragraph 1:
@ Subclause "7.7.11.3 The nextafter function"
Page 242
@ Subclause "7.7.11.4 The nextafterx function"
Page 243, paragraph 2:
In subclause 7.7, only "double" version mathematics
functions are defined, and a definition of its "float"
and "long double" version is derived by applying the rule
described below:
=09there are functions with the same name but with f
=09and l suffixes which are corresponding functions
=09with float and long double arguments and return
=09values.
But, every declaration for the "float" and "long double"
version should be explicitly written in subclause 7.7,
because the definition of some functions which have multiple
arguments can not be derived according to the above rule.
One expample is shown below.
The "nextafer" function has two double parameters.
=09double=09=09nextafter(double, double);
But the type of second parameter of its "float" and "long
double" versions, "nextaferf" and "nextaferl", are
ambigious.
According to the definition of "float" and "long double"
versions, second parameter may have type "float" and "long
double" respectively, such as in Annex D.9(page 465).
=09float=09=09nextafterf(float, float);
=09long double=09nextafterl(long double, long double);
On the other hand, the "nextafterx" function is defined as
follows
=09The nextaferx function is equaivalent to the nextafrer
=09function except that the second parameter has type long
=09double.
In this case, the type of second parameter has only type
"long double".=20
According to this definition, type of second parameter
of the "nextafter" function may have only the type "double".
=09float=09=09nextafterf(float, double);
=09long double=09nextafterl(long double, double);
Which declarations of nextafter are correct? It is ambigious.
2.15 Necessary rationale for the changes of some
environmental limits
@ Subclause "7.13.6.1 The fprintf function" Environmental limit
Page 293, line 2 in paragraph 14:
The minimum value for the maximum number of characters
produced by any single conversion is changed from 509 (in
the current ISO/IEC 9899) to 4095. And also, some of other
environmental limits are changed from ISO/IEC 9899. Please
describe a clear rationale for these changes.
2.16 Wrong notation in the example of fprintf/fscanf for
multibyte characters=20
1)
@ Subclause "7.13.6.1 The fprintf fumction" Examples
Page 294, line3 in paragraph 16:
@ Subclause "7.13.6.2 The fscanf functin" Examples 1,2,3,4=20
Page 302, line 3 in paragraph 18:
Two character (or, two byte) notation "$0" is used to
represent the first byte of a multibyte character. However,
in the original Amendment 1, a *single* square mark is used
for this purpose in order to clearly represen that it is
just *one* byte. =20
Please use one byte notation to represent the first byte of
a multibyte character.
2)
@ Page 294, paragraph 19:
The printed image of the example of fprintf is NOT correct
because the two byte notation $0 is used to represent one
byte. That is, positions of the right hand side vertical
bars are not aligned at the same column. They should be
printed in the same column.
Please use one byte notation to represent the first byte of
a multibyte character.
2.17 Wrong conversion specifier in the example of fprintf
@ Subclause "7.13.6.1 The fprintf function" Examples
Page 294, line 6 in paragraph 18:
"%13.1ls" should be corrected to "%13.11ls".
(The original Amendment 1 has the same mistake.)
2.18 The bahavior of a successful call to fseek and fsetpos
@ Subclause "7.13.9.2 The fseek function"
Page 317, paragraph 5:
@ Subclause "7.13.9.3 The fsetpos function"
Page 317, paragraph 3:
The description about the behavior of a successful call to
the fseek function was made clear in the current CD (SC22
N2620). However, the description of fsetpos about a
successful call was not changed from the ISO/IEC 9899.
The behavior of successful call to fseek should be same as
fsetpos.
Please update the description about the behavior of a
successful call to fsetps in the same way of fseek.
2.19 The redundunt sentences in mktime()
@ Subclause: 7.16.2.3 The mktime function
page 360, paragraph 3-6:
The lst sentence in the paragraph 5 and all sentences in
the paragraph 6 are entirely the same as all sentences of
the paragraph 3 and 4. The last sentence in paragraph 5 and
all sentences in paragraph 6 should be dropped.
2.20 Missng iswblank() in the description of iswctype()
@ Subclause "7.18.2.2.2 The iswctype function"
Page 377, paragraph 3:
Please add "iswctype(wc, wctype("blank")) // iswblank(wc)"
2.21 Incorrect parameter type of the nextafterx function
@ Annex "D.9 Mathematics <math.h>"
Page 465, line 15-16:
The "nextafterxf" and "nextafrerxl" functions are declared
as follows.
=09float=09=09nextafterxf(float, long float);
=09long double=09nextafterxl(long double, long long double);
Each second parameter shall have type "long double".
2.22 Descriptions for some functions are not found
@ Annex "F.9.3 Exponential and logarithmic functions"
Page 499-501:=20
A description for "scalbln" function is not found.
@ Annex "F.9.6 Nearest integer functions"
Page 503-505:
A description for "llrint" and "llround" functions are not
found.
@ Annex "F.9.8 Manipulation functions"
Page 506:
A description for "nextafterx" function is not found.
2.23 No more "common warning"
@ Annex "J Common Warnings"
Page 530, paragraph 2:
Following warning is no more "common warning".
=09- A function has return statements with and without
=09 expressions.
In subclause 6.6.6.4 Return statement(page 147),
"Constrains" has been changed from previous draft and
the following second sentence is appended:
=09A return statement with an expression shall not
=09appear in a function whose return type is void.
=09A return statement without an expression shall only
=09appear in a function whose return type is void.
This means a function shall not have return statements both
with and without expression. It is an undefined behavior.
2.24 Incomplete Annex K Portability issues=20
@ "Annex K Portability issues"
Page 532-554
Undefined/unspecified/implementation-defined behaviors
descreibed in "Amendment 1" are not included in the Annex
K1-K3. Please add the summary of them to Annex K1-K3.
3. Further Comments on SC22 N2618
---------------------------------
Japan has further comments on some of SC22/WG14's
dispositions described in SC22 N2618 (Disposition of Comments
Report on CD Registration for CD 9899: Informationtechnology -=20
Programming languages - Programming Language C (Revision of
ISO/IEC 9899:1993)).
3.1 The 64 bit data type should be optional
> 1. Technical Comments
> 1) Type long long int and lldiv_t should be optional.
>=20
> Paragraph 1 of subclause 5.2.4.1 (page 19 in draft 9),=20
> paragraph 3 of subclause 6.1.2.5 (page 32 in draft 9),=20
> constraints of subclause 6.5.2 (page 83 in draft 9), and
> paragraph 2 of subclause 7.13 (page 258 in draft 9):
>=20
> Type (unsigned) long long int is introduced into the draft 9
> as a mandatory part of the standard C. The maximum and
> minimum values for an object of type (unsigned) long long
> int are defined in the subclause 5.2.4.2. These values need
> to be represented by using 64 bit data type. Implementation
> of type (unsigned) long long int, however, is too hard for
> the compiler on the currently widely used 16 or 32 bit
> architecture machines. The cross compiler on the small
> machine must especially face a big difficulty when
> implementing type (unsigned) long long int. Therefore,
> type (unsigned) long long int should be a part of an=20
> optional specification or a part of the common extension of
> the standard C.
>=20
> A new type lldiv_t defined in subclause 7.13 should be
> reconsidered as well as type long long int.
>=20
> WG14: The Committee believes that the current WD is specifing current
> pracitice. The Committee also believes that the benifit to the use=
r
> community out weights the cost of implementation for this feature.
>=20
Japanese original comment is not proposing to drop the
specification of the type long long int at all. Japanese
comment does not intend "all-or-nothing" about long long
int. Japan is just proposing that "the 64 bit data type"
should be OPTIONAL, not mandatory. The above WG14's
disposion does not seem to explain an appropriate reason to
dispapprove "optional."
Japan, of course, knows well that there are the users who
need the 64 bit data type and also knows well it is possible
to implement the 64 bit data type even on the 16 or 32 bit
architecture machine even if it is a hard work, however, a
population of the 64 data type users are NOT the whole of
the C language user community. Japan thinks that there are
still significant nubmers of users who must be in trouble
with an unnecessary FAT implementation of the mandatory 64
bit data type.
Actually, for example, there are lots of developers and
vendors of small embeded system who are imposed to use or
develop "the ISO C comforming implememtaion" by their
customers/cliants or employers even if the 64 bit date is
comletely unnecessary to develop their system. In this
case, the 64 bit data type is just only a heavy burden
for them. The implementation of 64 bit data type is not the
benefit to this kind of users community at all. This is
just one of the examples.
So, Japan thinks that the words "the benifit to the user
community" in WG14's disposition does not express the real
situation. Correctly speaking, in the user community, there
are people who get the benefit from the 64 bit data type,
but, on the other hand, there are still a lot of people who
feel a disadvantage in the fat implementation of the 64 bit
data type.
So, please reconsider to make the 64 bit datat type
optional. (Japan does NOT mean to drop the long long int
itself.)
3.2 The function atoll() is redundant as the ISO C language
standard
> 1. Technical Comments
> 3) Function atoll() should be dropped.
>=20
> Subclause 7.13.1.4 (page 260 in draft 9):
>=20
> A new function atoll() is redundant for the standard C.
> (Every ato*() functions can be replaced by strto*().)
> The functions which can be directly replaced by other
> functions should not be included in the standard C. Not
> introducing redundant functions was one of the important
> policies of development of the Amendment 1. This policy is
> clearly described in the annex B.3 of the Amendment 1. If
> the committee had determined to include the function atoll()
> by some strong reason, why are NOT atod(), atold() included
> in the draft 9? Please drop atoll() from the draft, or please
> document a clear rationale which describes the reason why only
> atoll() was added.=20
>=20
> WG14: The Committee discussed this, and believes that this feature
> is currently existing practice. The consensus of the Committee
> is that the simple interface of this function is usefull to the
> user community.
Japan can not agree a direct addition of extra function only
by the simple reason "it is currently existing practice" and
"the simple interface of it is useful to the user
community." If "the simple interface is usefull to the user
community" is so importnat, why atod() and atold() are not
added? The atod() and atold() provide the simple interface
to the user community as well as atoll(). It seems there is
no policy and no criteria to make the language standard
here. Introducing new ato*() to the ISO C standard is
apparently break "the spirit of C" described in the Charter
of C9X:=20
- Keep language small and simple
- Provide only one way to do an operation
Japan requests again here:
Please drop atoll() from the draft, or please document a
CLEAR RATIONALE which describes the reason why ONLY atoll()
was added and the reason why other ato*() are NOT added.=20
Please make the criteria of intorduction of new functions
clear.
3.3 Example of ## operator
> 1. Technical Comments
> 5) Illegal example of ## operator
>=20
> Paragraph 4 (example) of subclause 6.8.3.3 (page 131 in
> draft 9):
>=20
> In the Example of the ## operator(paragraph 4 of
> subclause 6.8.3.3 (page 131)), that is,
> =09-----------------------------------------------------
> =09=09=09#define hash_hash # ## #
> =09=09=09#define mkstr(a) # a
> =09=09=09#define in_between(a) mkstr(a)
> =09=09=09#define join(c, d) in_between(c hash_hash d)
>=20
> =09=09=09char p[] =3D join(x, y); /* equivalent to */
> =09=09=09=09 /* char p[] =3D "x ## y"; */
>=20
> =09 The expansion produces, at various stages:
>=20
> =09 join(x, y)
> =09
> =09=09 in_between(x hash_hash y)
>=20
> =09 in_between(x ## y) ---- line (A)
>=20
> =09=09 mkstr(x ## y)
>=20
> =09 "x ## y"
> =09-----------------------------------------------------
> =20
> an object-like macro "hash_hash" is replaced by "##" at
> line (A). Well then, what kind of preprocessing-token is
> the "##" at line (A)?=20
>=20
> First, we can not find out any preprocessing-token other
> than "operator" for ##, therefore, the ## at line (A)
> must be the operator. Right? If so, the following
> description in the example must be incorrect:
> =09In other words, expanding hash_hash produces a new
> =09token, consisting of two adjacent sharp signs, but
> =09this new token is not the catenation operator.
>=20
> This description certainly says that ## is a token, but
> it is not the operator.=20
>=20
> Well, for the above description, should we read like
> the following sentence?
> =09...this new token is the operator as
> =09preprocessing-token, but does not function as the
> =09catenation operator.
>=20
> Even if so, this situation violates the Constraints of
> subclause 6.1.5 "Operator"(page 45 in draft 9) unless
> "##" in line (A) is considered as an operator:
> =09The operators # and ## shall occur in macro-defining
> =09preprocessing directives only.
>=20
> If we think a case that "##" is not a single
> preprocessing-token, then a behavior of this example must
> be undefined because of a paragraph 3 of subclause 6.8.3.3
> "the ## operator" (page 130 in draft 9):
> =09If the result is not a valid preprocessing token,
> =09the behavior is undefined.
>=20
> Anyway, whichever we choose, that is, the violation of
> the constraints or the undefined behavior, this example
> is not suitable for the example of the standard C.
>=20
> WG14: The current WD has new preprocessor token wording, that=20
> the Committee believes make the WD clearer in the area. =20
> The example is correct.
There are NO improvement about this problem in the current=20
CD (SC22 N2620.) =20
Please refer to:
"6.1.5 Operators", page 56, line 2-3 in paragraph 2:
> The operators # and ## (also spelled %: and %:%:, respectively)
> shall ocure in macro defining preprocessing directives only.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"6.8.3.3 The ## operator", page 163, line 8-9 in paragraph 3:
> If the result is not a valid preprocessing token,
> the behavior is undefined.
These specifications still inconsistent with the description
of the example.
Japan requests again here:
Please reconsder carefully the above issue.=20
3.4 Old reference to ISO/IEC 646
> 2. Editorial Comments
> 1) The reference ISO/IEC 646:1983 must be ISO/IEC 646:1991.
>=20
> Paragraph 1 of clause 2 (page 2 in draft 9):
>=20
> The normative reference for ISO 7-bit codes character set is=20
> defined as ISO 646:1983. That is old. It must be the
> latest one ISO/IEC 646:1991.
>=20
> WG14: The WD will be corrected.
The clause "2 Normative references" of the current CD(SC22
N2620) still referes to ISO/IEC 646:1983. The Annex A
"Bibliography" also refers ISO/IEC 646:1983.
Japan requests again here:
Please correct them.
3.5 Locale-specific behavior
> 2. Editorial Comments
> 2) Locale-specific behavior
>=20
> Paragraph 4 of Clause 4 (page 6 in draft 9):
>=20
> The description "an implementation shall be accompanied by a
> document that defines all implementation-defined
> characteristics and all extensions." should also mention
> "the locale-specific behavior" which is defined in the
> subclause 3.13.
>=20
> WG14: The WD will be corrected.
There is no correction in the current CD (SC22 N2620).
Please correct it.
3.6 Terminology of a null character
> 2. Editorial Comments
> 4) Terminology of a null character
>=20
> A many variety of the representation of "null character"
> is used in the draft 9.
> For example,=20
> - A byte with all bits zero, subclause 5.2.1.2 (page 17)
> - '\0', subclause 6.1.3.4 (page 43)
> - code of value zero, subclause 6.1.4 (page 44)
> - \0 escape sequence, footnote 33 (page 44)
> - zero-valued code, subclause 6.5.7 (page 104)
> - code value zero, subclause 7.1.1 (page 139)
> - code with value zero, subclause 7.13.8.1 (page 277)
> - terminating zero code, subclause 7.13.8.1 (page 278)=20
>=20
> So, they should be represented by using a same term.
>=20
> WG14: The Committee discussed this issue, and reached the consensus
> that a more detailed proposal would be needed to make such a=20
> major change.
In the current CD (SC22 N 2620):
1) Subclause "6.5.8 Initialization"
Page 133, line 3 in paragraph 18:
"(including the terminating zero-valued code...)"
should be changed to
"(including the terminating null wide character (defined
in 7.1.1)...)"
2) Subclause "7.14.8.1 Multibyte string functions" Returns
Page 343, line 3 in paragraph 4:
"terminating zero code"
should be changed to
"terminating null character (defined in 5.2.1)"
3.7 Placemaker
> 2. Editorial Comments
> 5) Placemaker should be included in preprocessing token.
>=20
> Paragraph 1 (syntax) of Subclause 6.1 (page 26 in draft 9):
>=20
> Placemaker defined in 6.8.3.2 is not included in
> the syntax of preprocessing token. It should be included.
> =20
> WG14: The "placemarker" preprocessing tokens are conceptually=20
> introduced during translation phase 4 and are conceptually=20
> removed before the end of phase 4; their only function is=20
> to ensure that empty macro arguments are distinct entities=20
> during macro replacement, rather than vanishing too soon.
> Because "placemarker" preprocessing tokens cannot exist=20
> in the program source file, it would be inappropriate and=20
> confusing to show them in the formal grammar.
Japan requests to add the WG14's above explanation as a
footnote of placemarker.
3.8 A double argument for the conversion specifier
> 2. Editorial Comments
> 14) A double argument for the conversion specifier
>=20
> Subclause 7.12.6.1 (page 232 - 233 in draft 9) and
> subclause 7.18.2.1 (page 308 - 309 in draft 9):
>=20
> In the description about the conversion specifier f, F, e,
> E and G of the function f[w]printf,=20
> "a double argument representing a floating-point number
> is..."
> should be changed to=20
> "a double argument representing a normalized
> floating-point number is..." ^^^^^^^^^^
> in order to clarify the range and the definition of the
> double argument.
>=20
> WG14: The Committee discussed this comment, and came to the=20
> consensus that this is not an editoral issue, some floating
> point arithmetics support denormal numbers and infinities.
> There will need to be a detailed proposal to support this=20
> change.
The original intention of Japanese comment is to point out
that the current description:
"A double argumant representing a floating number is
converted to ...[-]ddd.ddd...
A double argument representing an infinity is converted
to ...[-]inf or [-]infinity
A double argument representing a NaN is convered to ...
[-]nan or [-]nan(n-char-sequence)..."
is not appropriate as a strict language standard
specification because "a floating-pount number" (defined in
"5.2.4.2.2 Characteristics of floating types <float.h>"),=20
as WG14 mentions above, may include an infinity and a Nan
so that the current description can be reasd as an infinty
can be converted to [-]ddd.ddd or [-]inf and also NaN can be
converted to [-]ddd.ddd or [-]Nan.
Therefore, Japan re-proposes to change the above description
to:=20
"A double argument representing an infinity is converted
to ...[-]inf or [-]infinity...
A double argument representing a NaN is converted to ...
[-]nan or [-]nan(n-char-sequence)..."
A double argumant representing a floating number except
an infinity and a NaN is converted to ...[-]ddd.ddd..."
This change should be applied to the description about the
conversion specifier f, F, e, E and G of the function
f[w]printf().
_______________ end of Japan comments; beginning of UK comments _____
TITLE:
UK Comments for
ISO/IEC CD 9899 (SC22N2620) - Information Technology Programming Languages =
- C
The United Kingdom Votes NO with the following comments
Consideration should be given to the following:
(1) Change "complex" to be a true keyword.
(2) Remove the keyword "imaginary".=20
(3) Change the semantics of the keyword "restrict" to provide better
facilities for optimization. In brief, replace the present "simple lock"
semantics with "write once or read multiple" semantics.=20
(4) Remove the "long long" type, and reinstate the concept that "long" is
the longest integer type.=20
(5) Adjust the wording concerning multiple representations of the same
value for both integer and floating types where these are distinguishable,
and to require constants to generate consistent representations.=20
(6) The changes introduced in the floating-point model, in particular
with respect to exception handling, should be reconsidered
In addition, to the above points the UK is submitting the following
comments for consideration by WG14 These describe other issues that
should be addressed in the CD, while no one individual comment is
critical, the total number form a significant issue for the UK vote.=20
Public Comment Number PC-UK0001=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: various
Title: Errors in applying working papers to CD1
Detailed description:
This document lists the errors that have been made applying my approved
papers in CD1. They are listed in this Public Comment for the record.
N672 has not been applied.
The change to translation phase 2 in N673 has been made, but the footnote
has been lost.
7.1.8p3 should read "... returns.", not "... return"; see N675 DR147 for
details. The same correction is needed in annex C.
Footnote 30 should read "... and is not compatible with either.", not
"and it not compatible with either.". The change was introduced in N739
item 6a.
6.5.2p4 should read "... the specifier /int/ ...". The change was
introduced in N739 item 10.
7.16.3.6p6 should read "%p", not "%P" (this was introduced in N674 part
G). It is also inconsistent in its use of fonts - compare %B and %p.
7.11p3 has been misedited; it reads:
... which expand to positive integer constant expressions with type
/int/ and distinct values that have type compatible ... which expand to
positive integer constant expressions with distinct values that
are the signal numbers ... and should read:
... which expand to constant expressions with distinct values that
have type compatible ... which expand to positive integer constant
expressions with type /int/ and distinct values that are the signal =20
numbers ...
The change was introduced in N773 item 9B.
6.3.15p4 to p6 have not been changed as required by N774 item 1.
6.5.2.3p4 should read "The type is incomplete[94]", not "The type is
complete[94]". The change was introduced in N774 item 5.
Footnote 227 is missing the last line:
(char *) p < (char *) base + nmemb * size
The change was introduced in N783 item 13.
The changes relating to _exit() in N789 were omitted (at the discretion
of the editorial committee).
These will be resubmitted as a separate Public Comment.
7.16.1p1 should read "... and declares five types ...", not "... and
declares four types ...". The change was introduced in N793.
The comment within the pseudo-code in 7.16.2.6p3 is missing the last
line, which should read:
// if the offset cannot be determined.
The change was introduced in N793, though this also seems to be missing
that line.
Public Comment Number PC-UK0002=20
Category: Other: correction restoring original intent
Committee Draft subsection: 6.5.2.1
Title: Padding in unions - wording adjustment
Detailed description:
6.5.2.1p14 no longer makes sense. The words:
were the structure or union to be an element of an array should be
deleted.
Public Comment Number PC-UK0003
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent Committee Draft subsection: 6.3.2.2
Title: Adjustment to permitted incompatible argument types
Detailed description:
The excepted cases in 6.3.2.2p5 were meant to be slightly less
restrictive than the wording given. The second bullet point should read:
- both types are pointers to qualified or unqualified versions of
/void/ or of character types.
In addition, paragraph 6 should be part of paragraph 5; it is easy to
misparse the present arrangement. It could also be made easier by changing
the first words of the paragraph to: Furthermore, if the function ...
=20
Public Comment Number PC-UK0004
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.7
Title: Shift operators - wording tidy up
Detailed description:
Now that the term "width" is available, 6.3.7p3 could be reworded; the
last sentence should read:
If the value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined.
=20
Public Comment Number PC-UK0005
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent Committee Draft
subsection: 3.18, 6.8.5
Title: Make #error have the desired effect
Detailed description:
Consider the program:
#error foo
int main(void) { return 0; }
This does not violate any of 3.18p3:
The implementation must successfully translate a given program unless
a syntax error is detected, a constraint is violated, or it can determine
that every possible execution of that program would result in undefined
behavior but clearly ought to. A reasonable way to fix this is to add to
the end of 3.18p3:
The implementation must not successfully translate a program that
contains a #error preprocessing directive that is not part of a group
that is skipped by conditional inclusion.
=20
Public Comment Number PC-UK0006
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.4
Title: Clarification concerning overlapping string literals
Detailed description:
The first sentence of 6.1.4p6 does not fall into any of the three types
of behavior. Better wording would be:
It is unspecified whether these arrays overlap or not, provided that
their characters have the appropriate values.
Public Comment Number PC-UK0007
Comment 1.=20
Category: Other: outstanding problem
Committee Draft subsection: 6.5.3.1
Title: Problem with restrict and string literals
Detailed description:
Consider the function call:
fopen ("bar", "r");
Because both parameters of open() have restrict-qualified type, it is not
permitted for the two strings to share storage. However, an implementation
which shares string literals might do so, possibly without the programmer
realizing that the situation happened (for example, the first parameter
might be a macro defined in a makefile).
The correct solution is to exempt string literals from the rules
concerning restrict, but I am not familiar enough with the wording to try.
Public Comment Number PC-UK0008
Comment 1.=20
Category: Other: moving normative text to a normative section
Committee Draft subsection: Introduction, 1
Title: The definition of normative text should be normative.
Detailed description:
The Introduction contains the text:
The introduction, the examples, the footnotes, the references, and
the annexes are not part of this International Standard.
However, this text is not normative, and so it is not clear what text is
and is not normative. It is alss wrong.
Delete the sentence from the Introduction. Add a new paragraph 3 to
clause 1:
Annexes F and I are normative. The introduction, the examples, the
footnotes, the references, and the remaining annexes are not part of this
International Standard.
Public Comment Number PC-UK0009
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 7.16.3.6
Title: Lacuna in strftime() %z
Detailed description:
The description of %z does not say what to do if no time zone can be
determined. After the parenthesized clause, insert the words:
or no characters if no time zone is determinable.
Public Comment Number PC-UK0010
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.16.1
Title: _NO_LEAP_SECONDS should require a sensible value
Detailed description:
After the symbol _NO_LEAP_SECONDS in 7.16.1p2, add the comment:
_NO_LEAP_SECONDS // must be outside the range [-3600, +3600]
Public Comment Number PC-UK0011
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.16.1
Title: require a type for _NO_LEAP_SECONDS and _LOCALTIME.
Detailed description:
At the end of 7.16.1p2 add the words:
which are integral constant expressions with type /int/.
Public Comment Number PC-UK0012
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 7.16.1
Title: Fix definition of "broken-down time".
Detailed description:
The term "broken-down time" is clearly intended to refer to both the
types "struct tm" and "struct tmx". Change the last part of 7.16.1p3 from:
... representing times;
/struct tm/
which holds the component of a calendar time, called the /broken-down
time/; and /struct tmx/ which is an extended version of /struct tm/.
to:
... representing times; and
/struct tm/
and
/struct tmx/
which hold the components of a calendar time, called the /broken-down
time/, in two slightly different ways.
Public Comment Number PC-UK0013
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.1.2.5, 6.5.2.1
Title: Cleanup of flexible array structure members.
Detailed description:
The concept of flexible array structure members, otherwise known as the
"struct hack", has a number of minor problems that need fixing.
Furthermore, there are some nasty implications when such a structure is
used as a component of an aggregate type, this is forbidden.
6.1.2.5p17, bullet point 2, should read:
A /structure type/ describes a sequentially allocated nonempty set of
member objects (and, in certain circumstances, an incomplete array), each
of which has an optionally specified name and possibly distinct type.
6.5.2.1p2, first sentence, should read:
... except that the last member of a structure with more than one
named member may have incomplete array type; such a structure (and any
union containing, possibly recursively, a member whose type is such a
structure) shall not be the type of a member of a structure or of the eleme=
nt of
an array.
6.5.2.1p15 should be replaced by:
As a special case, the last member of a structure with more than one
named member may have an incomplete array type. This is called a /flexible
array member/, and the size of the structure shall be equal to the offset o=
f the last member of an otherwise identical structure that replaces the fle=
xible
array member with an array of unspecified length [*]. When an lvalue
whose type is a structure with a flexible array member is used to access
an object, it behaves as if that member were replaced with the longest
array, with the same element type, that would not make the structure
larger than the object being accessed; the offset of the array shall
remain that of the flexible array member, even if this would differ from
that of the replacement array. If this array would have no elements, then
it behaves as if it had one element, but the behavior is undefined if any
attempt is made to access that element or to generate a pointer one past
that element.
[*] The length is unspecified to allow for the fact that some
implementations may give array members different alignments according to
their length.
Change the start of paragraph 16 to:
Assuming that all arrays have the same alignment within structures,
then after the declarations:
struct s { int n; double d[]; };
struct ss { int n; double d[42]; };
the three expressions:
In paragraph 17, change:
/s1/ and /s2/ behave as if they had been declared as:
to:
the objects pointed to by /s1/ and /s2/ behave as if the latter two
identifiers had been declared as:
Public Comment Number PC-UK0014
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.5.8
Title: problems with initializing unsigned char arrays.
Detailed description:
Consider the following declaration:
unsigned char s [] =3D "\x80\xff";
The first element of the string literal has the value:
(char) 128
and the second element has the value:
(char) 255
If the type char is signed and CHAR_MAX is less than 128, these two
expressions are implementation-defined. In particular, on a
ones-complement implementation likely values are -127 and -0 respectively.
When these are converted back to unsigned char during the initialization,
then (if UCHAR_MAX is 255) they will be converted to 129 and 0
respectively. This is *not* intuitive.
Append to 6.5.8p17:
The value of each element is determined by converting the
corresponding numerical representation of the mapped character, or the
octal or hexadecimal escape sequence, directly to the array element
type, not via the type char.
Append to example 7 in 6.5.8p24:
The declaration:
unsigned char c [] =3D "\xFF";
is identical to:
unsigned char c [2] =3D { 0xFF, 0 };
and not to:
unsigned char c [2] =3D { (unsigned char)(char) 0xFF, 0 };
(the latter could be different if /CHAR_MAX/ is less than 255 and the
implementation-defined value of the expression /(char) 0xFF/ is not equal
to /254-UCHAR_MAX/).
Public Comment Number PC-UK0015
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 5.2.4.2.1
Title: ensure int can hold all characters and EOF
Detailed description:
To eliminate a pathological case, append to 5.2.4.2.1p2:
On a hosted implementation, INT_MAX shall be not less than UCHAR_MAX.
Public Comment Number PC-UK0016
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.1.1
Title: eliminate conditional keywords
Detailed description:
6.1.1 makes the keywords "complex" and "imaginary" only be "reserved" if
the header <complex.h> is included. This is a problem for two different
reasons.
Firstly, cautious programmers will assume that the keywords might be
needed at some later date, for example by a system header that they have
no control over. Therefore they will have to play safe and not use them.
The less cautious may use them, and then be burnt later when such a
change outside their control happens. Both cases bring the Standard into
disrepute.
Seeing that the decision has already been made to introduce new keywords,
there is little benefit in this approach unless it is going to be more
radical (for example, making complex types be unavailable on freestanding
implementations). And, even so, there are better approaches.
Secondly, the term "reserved" is being misused. This term (see 7.1.3)
means that an identifier may not be redeclared. Keywords are not
identifiers, and thus reservation is nonsense. In any case, the syntax
does not allow a keyword to be used as if it were an identifier.
Three alternatives are given here; my preference is for the third.
Alternative 1: delete 6.1.1 paragraph 2.
Alternative 2: if it is still viewed as desirable to make the names
"complex" and "imaginary" available to programmers not using <complex.h>,
then:
* Change the keywords in 6.1.1 to __complex and __imaginary.
* Add to 7.8 a new paragraph 4:
The macro /complex/ is defined to be /__complex/. If and only if the
macro /_Imaginary_I/ is defined, then the macro /imaginary/ is defined to
be /__imaginary/. Notwithstanding the provisions of subclause 7.1.3, it is
permitted to undefine the macros /complex/ and /imaginary/.
Alternative 3: since complex types are basic to the language while
imaginary types are an extension:
* Change the keyword imaginary in 6.1.1 to __imaginary.=20
* Add to 7.8 a new paragraph 4:
If and only if the macro /_Imaginary_I/ is defined, then the macro
/imaginary/ is defined to be /__imaginary/. Notwithstanding the provisions
of subclause 7.1.3, it is permitted to undefine the macro /imaginary/.
Public Comment Number PC-UK0017
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.3.9
Title: fix pointer comparison
Detailed description:
DR 172 addressed a number of defects in the rules for pointer comparison,
and the DR authors suggested new wording to fix this. This issue was also
raised in WG14 papers N720 and N783. Following other changes in the
Standard, this wording is no longer completely acceptable. Instead,
replace 6.3.9 paragraphs 3 to 5 with the following text.
The =3D=3D (equal to) and !=3D (not equal to) operators are analogous t=
o
the relational operators except for their lower precedence.[78] They yield
1 if the specified relation is true and 0 if it is false. The result has
type /int/. For any pair of operands, one operator shall be true and the
other false.
If both of the operands have arithmetic type, the usual arithmetic
conversions are performed. [[Insert the existing paragraph 5 here.]]
Otherwise the operands are pointers; if one is a pointer to an object or
incomplete type and the other has type pointer to a qualified or=20
unqualified version of /void/, the former is converted to the type of the
latter.
Two pointers shall compare equal if both are null pointers, both are
pointers to the same object (including a pointer to an object and a
subobject at its beginning), the same element of an array object, or the
same function, if both are pointers to one past the end of the same array
object, or if one is a pointer to one past the end of one array object and
the other is a pointer to the start of a different array object that
happens to be immediately after it in the address space.[79] Otherwise
they shall compare unequal.
Prepend to footnote 79:
Two objects may be adjacent in memory because they are adjacent
elements of some larger array object, because they are adjacent members of
a structure with no padding between them, or because they are unrelated
and the implementation chooses to place them adjacent in memory.
Public Comment Number PC-UK0018
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.7, 6.3.1.1
Title: merge predefined identifiers into one place
Detailed description:
The concept of predefined identifiers is found in two separate places:
6.1.2.7 and 6.3.1.1. The latter location is, I believe, historical cruft
from when __func__ was treated as a special entity. It would read
better to merge the two sections into one, and 6.1.2.7 is a better
location.
Delete subclause 6.3.1.1. Replace subclause 6.1.2.7 by the following:
6.1.2.7 Predefined identifiers
The identifiers described in the following subclauses shall be
implicitly defined by the implementation.
6.1.2.7.1 The identifier __func__
[[Insert the body of the present 6.3.1.1 here.]]
Public Comment Number PC-UK0019
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 5.1.1.2, 6.3.1.1
Title: handling of characters not in the execution character set
Detailed description:
Consider the code extract:
char *s =3D "\u30CE";
During translation phase 5 the universal character name is converted to a
multibyte character. However, it is not stated what happens if the
implementation does not have a representation for Katakana (30CE is within
the Katakana range of annex I). Therefore it is implicitly undefined.
Now consider the following translation unit:
#include <stdio.h>
void fff (void);
void \u30CE (void);
int main (void)
{
fff ();
\u30CE ();
return 0;
}
void fff (void)
{
printf ("This is %s\n", __func__);
}
void \u30CE (void)
{
printf ("Hello world!\n");
}
This is clearly strictly conforming (unless I've made an error :-).
Now consider the trivial change:
#include <stdio.h>
void fff (void);
void \u30CE (void);
int main (void)
{
fff ();
\u30CE ();
return 0;
}
void fff (void)
{
printf ("Hello world!\n");
}
void \u30CE (void)
{
printf ("This is %s\n", __func__);
}
This is now undefined on any implementation that cannot represent the
Katakana character set ! I have trouble believing that this was intended,
and I certainly feel that, if it is retained, it should be flagged in the
text of the Standard.
Public Comment Number PC-UK0020
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 4
Title: Adjust wording of footnote 2
Detailed description:
Footnote 2 is not particularly clear. Better wording would be:
A strictly conforming program can use conditional features, such as
those in annex F, provided that the use is guarded by an #ifdef directive
with the appropriate macro. For example:
[[followed by the existing example]]
Public Comment Number PC-UK0021
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 4
Title: Further requirements on the conformance documentation
Detailed description:
There are many things that the Standard requires to be documented, but
not all of them are listed in 4p4. Change it to:
An implementation shall be accompanied by a document that describes
all features that this International Standard requires to be described by
the implementation, including all implementation-defined characteristics
and all extensions.
Public Comment Number PC-UK0022
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 5.1.1.2
Title: Translation phase 6 is inconsistent
Detailed description:
Change TP 6 in 5.1.1.2p1 to read:
Adjacent character string literal tokens and wide string literal
tokens are concatenated.
Public Comment Number PC-UK0023
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.5.2.1, 6.5.6
Title: Removing implicit int, further lacunae
Detailed description:
The requirement for a type specifier has been omitted from 6.5.2.1 and
6.5.6. In each case, add a constraint:
At least one type specified shall be given in each
specifier-qualifier-list.
Public Comment Number PC-UK0024
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.5
Title: Replace footnote 25
Detailed description:
Footnote 25 is unclear in context. A better description of the situation
is in footnote 29. Replace the text of FN25 with that of FN29, and change
all references to the latter to be references to the former.
Public Comment Number PC-UK0025
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.3.2
Title: clarify the explanation of the types of an integer constant
Detailed description:
6.1.3.2p5 is rather difficult to read. Better would be to replace it with
a table, like this:
The type of an integer constant is the first one marked with an X in
the corresponding column of the table in which its value can be
represented:
Suffix: - - U L L LU LL LL LLU
Base: D O/H - D O/H - D O/H -
signed int X X
unsigned int X X
signed long X X X X
unsigned long X X X X
signed long long X X X X X X
unsigned long long X X X X X X
/signed extended/ X X X
/unsigned extended/ X X X
/any extended/ X X X
Notes: suffixes may be in either case, and where there are two
suffixes, in either order.
D =3D decimal
O/H =3D octal or hexadecimal
If an integer constant cannot be represented by any standard type in
its list, it may be represented by an extended integer type if there is
one that can represent that value. The type must be signed or unsigned if
so indicated.
Alternatively, the ad hoc nature of the present description could be
replaced by one more structured:
The type of an integer constant is the first one in the following
list in which its value can be represented:
/signed int/, /unsigned int/,
/signed long int/, /unsigned long int/,
/signed long long int/, /unsigned long long int/
and subject to the following restrictions:
- if suffixed by /u/ or /U/, then omit the signed types
- if decimal and not suffixed by /u/ or /U/, then omit the unsigned
types
- if suffixed by /l/ or /L/, then omit the first pair
- if suffixed by /ll/ or /LL/, then omit the first two pairs
If an integer constant cannot be represented by any of the types
permitted by the above, it may be represented by an extended integer type
if there is one that can represent that value and which has the same
signedness as at least one of the permitted standard types.
Public Comment Number PC-UK0026
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.4
Title: improve the example of character string literals
Detailed description:
Append to 6.1.4p7, the example:
When this is used to initialize a static array, the array has three
members that are initialized to /18/, the value of /'3'/, and /0/
respectively.
Public Comment Number PC-UK0027
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 5.1.1.2, 5.2.1, 5.2.1.2, 6.1.2, 6.1.2.5, 6.8
Title: inconsistencies in use of "basic" and "extended" character sets
and in their relationship to UCNs
Detailed description:
The Standard uses the terms "basic character set" and "extended character
set" at various places. However, the exact meaning of these two is not
clear, and this leads to confusion.
Consider the UTF-8 encoding (codes from 0 to 127 are single byte, codes
from 128 to 255 form part of multibyte characters with length from 2 to 5
bytes). There are five possible execution character sets:
[1] The 95 characters required by 5.2.1p3, plus the null character.
[2] The 128 single byte characters.
[3] The 2**31 multibyte characters.
[4] Set [3] minus set [1].
[5] Set [3] minus set [2].
(and corresponding source sets).
It is unclear whether the "basic character set" means [1] or [2]. The use
of the wording "at least the following members" in 5.2.1p3 implies that
the basic set can be larger than [1]. On the other hand, if the term is
taken to represent [2], then 5.1.1.2p2 would forbid using \u0040 to
represent the @ sign, something which I do not believe was intended, since
it means that the \u form would be forbidden for *all* characters in the
implementation-defined "basic" set.
Consideration of this and related matters has led me to believe that it
is most useful to have terms for [1] and for [4], while on the other hand
there is little or no need to refer to [2], [3], and [5]. Therefore
"basic character set" should represent [1] and "extended character set"
should represent [4]. To do this requires a number of changes.
Replace 5.2.1p1, second sentence, by:
Each set is further divided into a /basic/ set, whose contents are
given by this subclause, and an /extended/ set, consisting of zero or more
locale-specific members (which are not members of the basic set).
In 5.2.1p3, delete "at least" in the first sentence, and in the fourth
sentence change "In the execution character set" to "In the basic
execution character set".
Delete the last sentence of 5.2.1p3 ("If any other characters ... the
behavior is undefined"). It is useless for several reasons:
- If translation phase 1 is taken literally, all members of the extended
character set are replaced by UCNs, which consist of members of the basic
character set (this point is further addressed below). While some are
converted back in translation phase 5, all such characters are included in =
the
exemptions.
- It does not allow for UCNs in identifiers.
- If such a character was encountered, the preprocessing token it is in
is either not converted to a token (in which case the sentence does not
apply) or *is* converted; in the latter case, the constraint of 6.1p2 is
violated and this sentence has no effect.
Delete 5.1.1.2p2, and replace it by a constraint at the end of 5.2.1
(forming a new paragraph 6):
Constraint
A universal-character-name shall not specify (in either form) a
character short identifier less than 00A0 other than the following:
0024 0040 0060
This is a more consistent position for the restriction, and it has the
useful side effect of making it clear what the UCNs of the basic character
set *are*.
Replace 5.2.1.2p1, first bullet, by:
- The basic character set shall be present and shall be encoded using
single-byte characters.
There is no longer a need to check for the shift states of comments,
string literals, and so on, because during translation phase 1 these will
have been converted to a stateless representation using UCNs. Therefore
replace 5.2.1.2p2 by:
If a source file does not consist of a valid sequence of multibyte
characters, the behavior is undefined.
In 6.1.2.5p2, replace "required source character set enumerated in 5.1.2"
with "basic execution character set" (note that the execution set is more
sensible in this context than the source set).
The second sentence of 6.1.2p2 restricts UCNs in identifiers to those
listed in annex H. If some other UCN appears, it is unclear whether the
behavior is undefined, or whether the UCN is not part of the
identifier.
This is further complicated by the example in footnote 122. If the text
appeared in a source file, by translation phase 4 it would be processed
as:
#define THIS\u0024AND\u0024THAT(a,b) ((a)+(b))
and so the replacement list *does* begin with a character required by
subclause 5.2.1, and thus this is unambiguously a definition of the
object-like macro THIS. However, this completely wrecks the whole
point of 6.8p4 and FN122 (added in TC1).
Replace the second sentence of 6.1.2p2 with:
Only universal-character-names corresponding to the characters listed
in annex I are nondigits.[20]
and append to footnote 20:
Since 00A0 is not listed in annex I, but 00C0 is, the sequence of
characters a\u00C0b\u00A0 consists of two preprocessing tokens; the first
is an identifier made up of three nondigits.
(note also the correction to the annex cited).
Replace 6.8p4 by:
In the definition of an object-like macro, either the replacement
list shall be separated from the identifier by white space, or it shall
begin with one of the 26 graphic characters in the basic character set
other than ( _ or \ (and thus shall not begin with a =20
universal-character-name).[122]
Public Comment Number PC-UK0028
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.2.4.1
Title: clarify translation limit for identifiers using UCNs.
Detailed description:
In 5.2.4.1, change the relevant translation limits to:
- 63 significant initial characters in an internal identifier or a
macro name (a universal-character-name shall count as one)
- 31 significant initial characters in an external identifier (a
univeral-character-name shall count as 4 if less than 0000FFFF, and 8
otherwise)
or some other wording that reflects the Committee's intent if different.
Public Comment Number PC-UK0029
Comment 1.=20
Category: [one of the following]
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.2.4.2.2
Title: clarify rounding to nearest
Detailed description:
In 5.2.4.2.2p5, change the third case:
1 to nearest
to:
1 to nearest (if the value to be rounded is exactly between two
representable values, it is unspecified which is chosen)
Public Comment Number PC-UK0030
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.1.2
Title: Require UCNs to appear in translation phase 1
Detailed description:
Currently, a source file can contain:
\u12\
34
and it is unclear whether or not this is a universal character name. Add
to the end of 5.1.1.2 translation phase 2:
If a character sequence that matches the syntax of a
universal-character-name is produced by such splicing, the behavior is
undefined. =20
It is also unclear whether:
??/u1234
is a universal character name or not. I think the current wording allows
it, but a footnote would be a good idea.
Public Comment Number PC-UK0031
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.3.1.9, 7.18.2.1.9
Title: make ispunct() true for basic punctuation characters
Detailed description:
There appears to be no character for which it is required that ispunct()
is true. This is surprising, to say the least, as one would expect that it
is true for characters like '.' and '('.
Replace 7.3.1.9p2 by EITHER:
The /ispunct/ function tests for any printing character for which
neither /isspace/ nor /isalnum/ is true.
OR:
The /ispunct/ function tests for any character that is one of the 29
graphic characters in the basic execution character set or is one of a
locale-specific set of printing characters for which neither =20
/isspace/ nor /isalnum/ is true. In the "C" locale it returns true only
for the characters in the basic execution character set.
[These two are not equivalent outside the "C" locale.]
Public Comment Number PC-UK0032
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.1.2.1
Title: tidy-up specification of overlapping scopes
Detailed description:
The use of "non-overlapping" in 6.1.2.1p implies that the "scope" of an
identifier excludes any block where the identifier is redeclared. This is
inconsistent with the description of inner and outer scopes in paragraph
3; the latter is probably preferable.
Change the word "non-overlapping" in paragraph 1 to "different".
Public Comment Number PC-UK0033
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.2.2
Title: Fix wording relating to "number of arguments"
Detailed description:
6.3.2.2p2 states "the number of arguments shall agree with the number of
parameters". This does not clearly take account of varargs functions.
Change the wording to:
the number of arguments shall equal or, if the prototype ends with an
ellipsis (, ...), shall be no less than, the number of parameters
(excluding any ellipsis).
Public Comment Number PC-UK0034
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.2.3
Title: Adjust wording concerning qualifiers on structure members
Detailed description:
6.3.2.3p3 reads, in part:
If the first expression has qualified type, the result has the
so-qualified version of the type of the designated member.
This should read:
The result has all the qualifiers of the first expression and those
of the designated member.
Also add an example:
In:
struct s { int i; const int ci; };
struct s s;
const struct s cs;
volatile struct s vs;
the various members have the types:
s.i int
s.ci const int
cs.i const int
cs.ci const int
vs.i volatile int
vs.ci volatile const int
Public Comment Number PC-UK0035
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.3.2.4, 6.3.3.1
Title: Allow increment/decrement of complex objects.
Detailed description:
All the operators that can be applied to a real floating object can also
be applied to complex ones, with the sole exception of ++ and --. There is
no obvious reason for this exception (particularly since the ! operator
can be applied).
In 6.3.2.4p1 and 6.3.3.1p1, change "real" to "arithmetic".
Public Comment Number PC-UK0036
Comment 1.=20
Category: Normative change where the intent is unclear
Committee Draft subsection: 6.3.16
Title: Define the result of the assignment operator
Detailed description:
6.3.16p3 states:
An assignment expression has the value of the left operand after the
assignment, but is not an lvalue.
It is not clear what this means when the left operand is a volatile
object that changes through external causes - it could mean the value
stored, or it could mean the result of reading the object.
Replace these words with the unambiguous:
The value of the assignment expression is the value stored in the
left operand, but is not an lvalue.
Public Comment Number PC-UK0037
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.4
Title: Constant expression cannot contain the size of a VLA
Detailed description:
6.4 does not require a constraint for "sizeof(v)" where v has variable
length array type. FN83 also fails to notice this case.
Append to 6.4p3:
Any /sizeof/ operator shall have an operand whose size is defined to
be constant.
Move the reference to FN83 to the new end of the paragraph, and within
the footnote change:
not evaluated
to:
not evaluated when no component of the operand has variable length
array type
In 6.4p6 remove the words "sizeof expressions ... name of such a type".
Public Comment Number PC-UK0038
Comment 1.=20
Category: Feature that should be removed
Committee Draft subsection: 6.1.8
Title: UCNs should not be permitted in preprocessing numbers
Detailed description:
The syntax in 6.1.8p1 uses "nondigit", which used to represent the 52
letters plus underscore but now also includes the UCNs in Annex I. I
believe this is a mistake, and the syntax should be adjusted =20
accordingly.
Public Comment Number PC-UK0039
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 6.1.3.1
Title: Allow 'i' suffix for floating constants
Detailed description:
It should be possible to write an imaginary floating point constant
rather than having to multiply by the macro /I/. Furthermore, this macro
is not available in a free-standing implementation.
The obvious way to do this is to allow the suffix 'i' or 'I'. To do so:
In 6.1.3.1p1:
- Remove "floating-suffix/opt" from the various alternatives to
"decimal-floating-constant" and
"hexadecimal-floating-constant". =20
- Append "floating-suffices/opt" to each alternative for
"floating-constant".
- Add:
floating-suffices:
floating-suffix imaginary-suffix
imaginary-suffix floating-suffix
imaginary-suffix: one of
i I
Append to 6.1.3.1p4:
If the constant has the suffix /i/ or /I/, then its type and value
are that resulting when the constant without that suffix is multiplied by
the value of the macro /I/ defined in the header <complex.h> and add a
forward reference to 7.8.
Public Comment Number PC-UK0040
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.5.2.1
Title: Bitfields of non-standard types should require a diagnostic.
Detailed description:
If a bitfield is declared with a type other than plain, signed, or
unsigned int, the behavior is undefined. Since this can easily be
determined at compile time, it should generate a diagnostic. An exception i=
s
required for the type underlying /bool/, and perhaps for any type that
can have valid bitfields.
Delete the first sentence of 6.5.2.1p8.
Add to the end of 6.5.2.1p3:
A bit-field shall have a type that is a qualified or unqualified
version of /signed int/ or /unsigned int/, or of the type /bool/ defined
in the header <stdbool.h>.
or:
A bit-field shall have a type that is a qualified or unqualified
version of /signed int/ or /unsigned int/, of the type /bool/ defined in
the header <stdbool.h>, or of some other implementation-defined integer
type.
Public Comment Number PC-UK0041
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.5.2.2, 6.5.2.3
Title: An example uses an incomplete type in the wrong context
Detailed description:
6.5.2.3 example 3 uses the line:
enum f { c =3D sizeof (enum f) };
but 6.5.2.2p5 indicates that the type is not complete at the point it is
used in the constant expression, and so a constraint is violated. The
example must be reworded or deleted.
Public Comment Number PC-UK0042
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.4
Title: Clarify some aspects of inline
Detailed description:
In 6.5.4p6, add a footnote referenced at the end of the paragraph:
[*] The call need not be due to the direct appearance of the name of
the function at the point of calling; it may be through some kind of
indirection.
In 6.5.4p8, after:
because /fahr/ is also declared with /extern/
add:
(even though that declaration is not visible at the definition of
/fahr/)
Public Comment Number PC-UK0044
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.5.7
Title: Removal of implicit int - further lacunae
Detailed description:
In 6.5.7p3, the last sentence:
If the identifier is redeclared in an inner scope or is declared as a
member of a structure or union in the same or an inner scope, the type
specifiers shall not be omitted in the inner declaration.
are no longer needed, as the type specifiers cannot be omitted.
Public Comment Number PC-UK0046
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.7
Title: Correct ranges of bitfields in an example
Detailed description:
In 6.5.7 example 3, change the specified ranges:
- from "at least the range [-15, +15]" to "either the range [-15, +15] or
the range [-16, 15]=20
- from "values in the range [0, 31] or values in at least the range [-15,
+15]" to "values in one of the ranges [0, 31], [-15, +15], or [-16, +15]"
Public Comment Number PC-UK0047
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.8
Title: Handling of unknown preprocessing directives
Detailed description:
In the preprocessing phase (translation phase 4), consider the line:
# unknown command
It is unclear whether or not this requires a diagnostic. Presumably the #
punctuator will remain until translation phase 7 where it cannot fit in
the syntax, but even if so, this is less than clear. However, this is easy
to fix. In the syntax in 6.8p1, change group-part to:
group-part:
non-directive new-line
if-section
control-line
and add:
non-directive:
pp-tokens/opt
Then add a constraints clause:
Constraint
The first preprocessing-token (if any) in a non-directive shall not
be /#/.
Finally, delete 6.8.3p8, because this can no longer occur.
Public Comment Number PC-UK0048
Comment 1.=20
? Category: Other: unresolved issue
Committee Draft subsection: 6.1.7, 6.8.2
Title: Problems with UCNs in header file names
Detailed description:
Consider the line:
#include "a$b.h"
This will be changed, in translation phase 1, to:
#include "a\u0024b.h"
Both of these involve undefined behavior, but equally both are valid file
names on at least one common operating system. It is likely that
implementations that implement UCNs in a natural manner are going to have
problems deciding which of the names was intended.
I'm not clear what the answer is, but it needs addressing.
Public Comment Number PC-UK0049
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.8.1
Title: Handling of UCNs in character constants in #if directives
Detailed description:
Consider the line:
#if '\u0024' < 100
where dollar is in the single-byte execution character set. It is not
completely clear from 6.8.1p3 that the UCN is converted to a single
character, since this normally happens in translation phase 5.
In 6.8.1p3, last two lines of page 157 (postscript version), change:
... which may involve converting escape sequences into execution
character set members. Whether
=2E.
to:
... which may involve converting source character set members, escape
sequences, and universal character names into execution character set
members in the manner of translation phase 5. However, =20
whether ...
Public Comment Number PC-UK0050
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.1.2.8.1, 6.3.2.3
Title: Effects on other members of assigning to a union member
Detailed description:
6.3.2.3p5 has wording concerning the storing of values into a union
member:
With one exception, if the value of a member of a union object is
used when the most recent store to the object was to a different member,
the behavior is implementation-defined.
The requirement to be implementation-defined means that an implementation
must ensure that all stored values are not trap representations in the
types of other members, and thus, in effect, eliminates the possibility of
trap representations at all.
It turns out that the wording of 6.1.2.8.1 is sufficient to explain the
behavior in these circumstances, and the cited wording in 6.3.2.3 merely
muddles the issue. It should be removed; the rest of the paragraph can
stand alone.
Public Comment Number PC-UK0051
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 7.1.7
Title: true and false are not reserved identifiers
Detailed description:
7.1.7p3 defines "true" and "false" as macros, which thus a reserves them
in accordance with the third bullet of 7.1.3. FN138 suggests that an
implementation could use these names as enumeration constants, but they
are not reserved in that context. That is:
#include <stdbool.h>
#undef true;
complex long double true;
is strictly conforming.
Since the implementation in the footnote is a useful one (for the reasons
given), 7.1.7 should reserve these names at file scope, either explicitly
or by changing these two identifiers to be "const int"
(though of course this would give them an address).
Public Comment Number PC-UK0052
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 6.8.3
Title: Add a __VA_COUNT__ facility for varargs macros
Detailed description:
Unlike with function calls, it is trivial for an implementation to
determine the number of arguments that match the ... in a varargs macro.
There are a number of useful things that can be done with this (at the
least, providing argument counts to varargs functions). Therefore this
information should be made available to the macro expansion.
In 6.8.3p5, change
The identifier /__VA_ARGS__/ ...
to:
The identifiers /__VA_ARGS__/ and /__VA_COUNT__/ ...
Append to 6.8.3.1p2:
The identifier /__VA_COUNT__/ that occurs in the replacement list
shall be treated as if it were a parameter; it is replaced by a single
token which is the number of trailing arguments (as a decimal constant)
that were merged to form the variable arguments.
Public Comment Number PC-UK0053
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.4
Title: Require consistency if an implementation adds to <inttypes.h>
Detailed description:
7.20.3 reserves all names such as int11_t and uint_least22_t. This allows
implementations to define them in <inttypes.h>, but does not require these
names to be handled consistently. Adding such a requirement would aid
portability. This proposal does not require any types other than those
already required by the header.
[The following is a minimal change. If requested, I can rewrite the header =
to integrate the changes
better.]
Append to 7.4 as a new paragraph 5:
For each typedef name listed as /optional/ and which can be defined
as a type existing in the implementation, it is unspecified whether or not
the type is defined, but if it is provided, so shall the corresponding
limit and /fprintf/ macros (as with all the types in this header, the
/fscanf/ macros are optional).
Append to 7.4.1.1, 7.4.1.2, and 7.4.1.3 as a new paragraph 4:
Any other typedef name of these two forms is an optional type.
Append to 7.4.2 as a new paragraph 3:
Any optional types shall have /MAX/ and, if signed, /MIN/ macros with
the appropriate name and value as if explicitly included in the following
subclauses. For example, if the type /uint14_t/ is provided, then the
macro UINT14_MAX shall be provided with value exactly 16383.
Append to 7.4.4p1:
Any optional types shall have /fprintf/ and /fscanf/ macros with the
appropriate name and value as if explicitly included in the following
lists. For example, if the type /uint14_t/ is provided, then the
macros /PRIo14/, /PRIu14/, /PRIx14/, /PRIX14/, /SCNo14/, /SCNu14/, and
/SCNx14/ should be added to the lists below.
Public Comment Number PC-UK0054
Comment 1.=20
Category: Other: C++ conflict avoidance
Committee Draft subsection: 6.8.8
Title: Require that __cplusplus not be defined
Detailed description:
Add to 6.8.8 a new paragraph 5:
The implementation shall not predefine the macro /__cplusplus/, nor shall
it define this macro in any header defined in clause 7.
Public Comment Number PC-UK0055
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.8
Title: It should be explicitly possible to redefine I
Detailed description:
7.8p3 should end:
Not withstanding the provisions of subclause 7.1.3, it is permitted
to undefine and redefine the macro I.
This was clearly the intent.
Public Comment Number PC-UK0056
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.1.6
Title: Add a symbol giving the maximum alignment
Detailed description:
[I eventually decided <stddef.h> is the right place for this.]
Add a new macro to <stddef.h>:
_ALIGNMENT_ALL
which expands to an integer constant expression that has type
/size_t/, the value of which is the least common multiple of the
alignments of all object types.[*]
[*] If /p/ has pointer to character type and is suitably aligned for
some type /t/, then /(p + _ALIGNMENT_ALL)/ is also suitably aligned for
the same type /t/, no matter what /t/ is.
Possibly also add the macros:
_ALIGNMENT_INTS
_ALIGNMENT_FLOATS
_ALIGNMENT_POINTERS
which are the least common multiples of the alignments for integer types,
for floating types, and for pointer types respectively. Other names could
also be conceived of (_ALIGNMENT_STRUCTS, _ALIGNMENT_UNIONS,
_ALIGNMENT_SCALARS, etc.).
Public Comment Number PC-UK0057
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.13.2, 7.13.3, 7.19.3.10, 7.19.7
Title: Better locale handling for wide oriented streams
Detailed description:
7.13.2p6 associates an /mbstate_t/ object with each stream, and
7.13.3p11-13 state that this is used with the various wide-oriented
functions. On the other hand, 7.19.7p3 places very strict restrictions on
the use of such objects, restrictions that cannot be met through the
functions provided in the Standard while allowing convenient use of wide
formatted I/O.
Furthermore, an /mbstate_t/ object is tied to a single locale based on
the first time it is used. This means that a wide oriented stream is tied
to the locale in use the first time it is read or written. This will be
surprising to many users of the Standard.
Therefore, at the very least these objects should be exempt from the
restrictions of 7.19.7; the restrictions of 7.13 (for example, 7.13.2p5
bullet 2) are sufficient to prevent unreasonable behaviour. In addition,
the locale of the object should be tied and not affected by the current
locale. The most sensible way to do this is to use the locale in effect
when the file is opened, but allow /fwide/ to override this.
In 7.13.2p6, add after the first sentence:
This object is not subject to the restrictions on direction of use
and of locale that are given in subclause 7.19.7. All conversions using
this object shall take place as if the /LC_CTYPE/ category setting of the c=
urrent locale is the setting that was in effect when the orientation of the=
stream was set
with the /fwide/ function or, if this has not been used, when the stream
was opened with the /fopen/ or /freopen/ function.
In 7.19.3.10, add a new paragraph after paragraph 2:
If the stream is successfully made wide oriented, the /LC_CTYPE/
category that is used with the /mbstate_t/ object associated with the
stream shall be set to that of the current locale.
In 7.19.7p3, append:
These restrictions do not apply to the /mbstate_t/ objects associated w=
ith streams.
Public Comment Number PC-UK0058
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.13.4.3
Title: Unclear how many times tmpfile() can be called.
Detailed description:
Nowhere does the Standard state how many times tmpfile() can be called,
nor does it state that several successful calls will actually access
different files !
Append to 7.13.4.3p2:
The file will be different from any other existing file, including
any opened by a previous successful call to the /tmpfile/ function.=20
Add a new part to 7.13.4.3:
Recommended practice
It should be possible to open at least /TMP_MAX/ temporary files
during the lifetime of the program, and no limit on the number
simultaneously open other than this limit and any limit on the =20
number of open streams (FOPEN_MAX). The limit of /TMP_MAX/ could be
shared with calls to /tmpnam/.
Public Comment Number PC-UK0059
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.8
Title: Add a description of the start symbol to the preprocessing grammar
Detailed description:
There is (still) no clear description of the grammar that a preprocessing
file needs to obey. That is, the grammar is there but its applicability is
not given.
Add a new paragraph to 6.8 just before paragraph 5:
As discussed in 5.1.1.1, the unit of program text before
preprocessing (at the start of translation phase 4) is a preprocessing
file. As shown in the grammar above, this consists of a sequence of
conditional inclusion blocks, other preprocessing directives, and other
text.
Public Comment Number PC-UK0060
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 7.2
Title: Clarify multiple insertions of <assert.h>
Detailed description:
The rules for including <assert.h> are partly in 7.1.2 and partly
unstated. They should be stated more clearly in 7.2. Add to the end of
7.2p1:
The /assert/ macro is redefined according to the current state of
/NDEBUG/ each time that /<assert.h>/ is included.
Public Comment Number PC-UK0061
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.2.1
Title: Explicitly allow assert on non-integer arguments
Detailed description:
A DR response stated that assert need not correctly handle arguments
which are not of type int but can be compared with zero. At the very
least, this forbids arguments which are unsigned int or long, let
alone other scalar types. Since it is trivial to have the macro convert
any scalar to truth value integer by prefixing it with the !! operator,
this restriction should be removed.
In 7.2.1.1p1, change "int expression" to "scalar expression", where the
word "scalar" is in italics. Add to paragraph 2, either after the first
sentence or at the end:
The argument of the /assert/ macro is any expression with scalar type.
Public Comment Number PC-UK0062
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.13.3, 7.13.5.4
Title: Provide a way to make the standard streams binary
Detailed description:
7.13.3p7 states that the three standard streams are text. This makes it
impossible to write programs like "cat" on systems where text and binary
streams are not the same.
There are a number of ways to provide this facility. Here is my prefered
one: add a new paragraph to 7.13.5.4 before paragraph 3:
If /filename/ is a null pointer, the /freopen/ function attempts to
change the mode of the stream to that specified by /mode/, as if the name
of the file currently associated with the stream had been used. =20
It is implementation-defined which changes of mode (if any) are permitted
and under what circumstances.
Public Comment Number PC-UK0063
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.13.9
Title: Provide a way to compare fpos_t values.
Detailed description:
There is no way to determine whether two fpos_t values represent the same
position in a file.
Therefore, it is not possible to do operations such as the following:
- open a file
- move through it, looking for some mark
- note the position using fgetpos()
- rewind
- move through it again to the same position, using calls to fgetpos() to
determine where you are, rather than relying on having made exactly the
same sequence of reads and seeks
Add a new function to 7.13.9:
7.13.9.X The fcmppos function
Synopsis
#include <stdio.h>
struct fcmppos fcmppos (fpos_t* pos1, fpos_t* pos2, FILE *stream)
Description
The /fcmppos/ function compares the values pointed to by /pos1/ and
/pos2/, which must both refer to the stream /stream/. If either of the
first two arguments is a null pointer, the result of a call to the =20
/fgetpos/ function on the stream is used instead. If the stream has been
written to at any point before the later of the two positions, the
behaviour is undefined.
Returns
The value returned is a structured type containing at least the
following fields:
int before; // Less than, equal to, or greater than zero
// according
// to whether /*pos1/ is before, at the same
// location
// as, or after /*pos2/ in the file.
int mbstate; // Zero if and only if the two positions have the
// same
// multibyte parsing status.
It will also be necessary to add /struct fcmppos/ to the start of 7.13.
Public Comment Number PC-UK0064
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.13.8.1, 7.13.8.2
Title: Clarify the actions of fread and fwrite
Detailed description:
The exact behaviour of fread and fwrite are not well specified,
particularly on text streams.
In 7.13.8.1p2, add after the first sentence:
For each object, /size/ calls are made to the /fgetc/ function and
the results stored, in the order read, in an array of /unsigned char/
exactly overlaying the object.
In 7.13.8.2p2, add after the first sentence:
For each object, /size/ calls are made to the /fputc/ function,
taking the values (in order) from an array of /unsigned char/ exactly
overlaying the object.
Public Comment Number PC-UK0065
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: various
Title: What is the precision of floating point calculations ?
Detailed description:
DR 063 asked, for C89, what was the required precision of the results of
the various floating point operators and functions. To date this has not
been answered. I am not aware enough of the issues to be able to write a
good answer myself, but references to IEC 559 and anne x F are not a
sufficient solution.
Public Comment Number PC-UK0066
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: various
Title: The term "access" is not well defined.
Detailed description:
The term "access" is not well defined. From context, it sometimes appears
to mean "read the value", and sometimes "read or write the value". This
ambiguity sometimes makes it hard to understand what is actually meant.
There needs to be a definition in clause 3, and all uses of the term need
to be checked for the read-only / read-write problem. Probably the best
approach is to define it as "read or write", and to find and fix the
places where "read" is meant.
An example where "access" clearly means "read" is in 6.5.3.1p5:
A reference to a value means either an access to or a modification of
the value.
So "access" presumably means read but not write. But if so, then 6.5.3p6:
What constitutes an access to an object that has volatile-qualified
type is implementation-defined.
must also exclude writing. But that would mean that what constitutes a
write to a volatile object is *not* implementation-defined, but rather
undefined ! Since this is obviously not the intent, there is a clear
contradiction that needs resolving.
There are plenty of other instances; for example, 6.3p6:
... If a value is stored into an object ... the type of the lvalue
becomes the effective type of the object for that access ...
where writing is clearly meant to be included.
However, the point is not to address these individual cases but rather
make the whole Standard consistent.
Public Comment Number PC-UK0067
Comment 1.=20
Category: Other: tidy up (technically normative)
Committee Draft subsection: 7.14
Title: tidy up definitions of <stdlib.h> macros
Detailed description:
In 7.14p3, change:
EXIT_SUCCESS
which expand to integer expressions which ...
to:
EXIT_SUCCESS
which expand to integer constant expressions which ...
and change:
MB_CUR_MAX
which expands to a positive integer expression whose value ... never
greater than /MB_LEN_MAX/.
to:
MB_CUR_MAX
which expands to a positive integer expression whose type is /size_t/
and whose value ... never greater than /MB_LEN_MAX/. This is not a
constant expression: it may change whenever the locale changes.
Public Comment Number PC-UK0068
Comment 1.=20
Category: Other: rewording to show consistency
Committee Draft subsection: 7.14.6.2
Title: Change the description of div() to show consistency
Detailed description:
Change the description of the div function (7.14.6.2) to:
Description
The /div/ function computes the quotient and remainder of the
division of the numerator /numer/ by the denominator /denom/.
Returns
The /div/ function returns a structure of type /div_t/, comprising
both the quotient and the remainder. The structure shall contain the
following members, in either order:
int quot; // quotient, equivalent to (numer / denom)
int rem; // remainder, equivalent to (numer % denom)
If either part of the result cannot be represented, the behavior is
undefined.[*]
[*] The function is equivalent to:
div_t div (int numer, int denom)
{ return (div_t) { .quot =3D numer / denom, .rem =3D numer % denom }; =
}
Alternatively, simply replace the entire description by the code in the
suggested footnote.
Public Comment Number PC-UK0069
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: Annex G
Title: Reorganise annex G as two separate items
Detailed description:
Annex G currently gives a specification for IEC 559 compatible complex
types *and* for imaginary types, all conflated. These are separate
concepts which can each be useful. Annex G should be split into two
separate parts.
The first annex is "Imaginary Types" and is normative. It begins
something like:
This annex specifies imaginary types. An implementation shall either
conform to all the requirements of this annex, and shall define the macro
/_Imaginary_I/ in <complex.h>, or it shall not provide such types, shall
not define the macro /_Imaginary_I/, and shall not define the keyword
/imaginary/.
It then includes all the imaginary type parts: G.2, G.3, G.4.1p1-3, G.4.2
(except for the words "and exceptions"), G.5p1, G.6.
The second annex is "IEC 559 compatible complex arithmetic" and is
normative. It is introduced with words like those in F.1, including:
An implementation that defines __STD_IEC_559_COMPLEX__ conforms to
the specification in this annex.
It then includes G.4.1p4-7, G.4.2p2, G.5 except p1.
Public Comment Number PC-UK0070
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.9
Title: Type-generic macros should be generally useful
Detailed description:
7.9 introduces the concept of type-generic macros, but these are only
available for a small range of mathematical functions. This facility
should be made generally available so that they can be used for general
programming.
Public Comment Number PC-UK0071
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.8.2
Title: Clarify included file process
Detailed description:
6.8.2p3 ends:
If this search is not supported, or if the search fails, the=20
directive is reprocessed as if it read
#include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if
any) from the original directive.
The wording is technically incorrect, precisely because the original
directive could contain angle brackets within the quotes whereas an
h-char-sequence cannot. Better wording would be:
If this search is not supported, or if the search fails, the
directive is reprocessed as if it read
#include <h-char-sequence> new-line
with the identical contained sequence from the original directive (if
the q-char-sequence contains a > character, this is retained in the name
searched for even though it could not appear in a true h-char-sequence).
Public Comment Number PC-UK0072
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.11.1.1, 7.14.4
Title: _exit function
Detailed description:
As part of a working paper (N789), I suggested that C provide an _exit()
function like that in POSIX, and signal handlers should be allowed to call
this function. After further discussion, it would still appear that this
function is useful and can be specified in a way that is completely
conformant to POSIX. However, I have made some improvements to the wording
in N789.
Make the following changes:
In 7.11.1.1 paragraph 5, change:
or the signal handler calls any function in the standard library
other than the /abort/ function or the /signal/ function=20
to:
or the signal handler calls any function in the standard library
other than the /abort/ function, the /_exit/ function, or the /signal/
function
Add a new subclause 7.14.4.4 within 7.14.4 (Communication with the
environment), renumbering subsequent subclauses.
7.14.4.4 The _exit function
Synopsis
#include <stdlib.h>
void _exit (int status);
Description
The /_exit/ function causes normal program termination to occur, and
control to be returned to the host environment. No functions registered by
the /atexit/ function or signal handlers registered by the /signal/
function are called. The /_exit/ function never returns to the caller.
The status returned to the implementation is determined in the same manner
as for the /exit/ function. It is implementation-defined whether open
output streams are flushed, open streams closed, or temporary files
removed.
Public Comment Number PC-UK0073
Comment 1.=20
Category: Other: clarification
Committee Draft subsection: 6.5.5
Title: clarify order of evaluation of expressions within full declarators
Detailed description:
6.5.5p3 states:
The end of a full declarator is a sequence point.
However, a full declarator can contain several expressions that require
evaluation, and no ordering is stated. For example:
int n;
/* ... */
int v [++n][++n];
It is not clear whether this is undefined behavior (two modifications to
n), unspecified behavior (which expression is evaluated first), or has a
defined order.
Change the cited wording to:
The end of a full declarator is a sequence point; the various
expressions within a full declarator are evaluated using the same rules
for expression ordering as if they were combined into a single expression
using the + operator.
Public Comment Number PC-____
Comment 1.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.2.2.3
Title: a pointer to an object should point to its first byte
Detailed description:
Add a requirement that a pointer to an object should point to its first
byte when cast to a pointer to a character type. Without this requirement,
functions such as memcpy() and fread() will not work as intended.
In subclause 6.2.2.3 add a new paragraph after paragraph 7:
If a pointer to an object is converted to a pointer to character
type, the result points to the lowest addressed byte of that object.
Successive increments of the result, up to the size of the original =20
object, yield pointers to the remaining bytes of the object.
Public Comment Number PC-____
Comment 1.
Category: Inconsistency
Committee Draft subsection: various
Title: problems with UCNs
Detailed description:
Further examination of UCNs shows that they have many problems associated
with them, and in particular produce very different behaviour than would
occur with C89.
The following example was presented in comp.std.c by Antoine Leca
<Antoine.Leca@renault.fr> and is summarised by me:
What is the effect of the following code:
#include <stdio.h>
#define str(s) #s
int main(void)
{
printf (" # of <%s> is <%s>\n", "$", str ("$"));
return 0;
}
Since $ is not part of the basic character set, this is not strictly
conforming. However, assume that the implementation has a representation
for $. Then, under C9X the output is clearly:
# of <$> is <"$">
Under C9X, the output is probably one of:
# of <$> is <"\u0024">
or
# of <$> is <"\$">
At Translation Phase 1, both $s will be converted to \u0024, and so the
source will become:
#include <stdio.h>
#define str(s) #s
int main(void)
{
printf (" # of <%s> is <%s>\n", "\u0024", str ("\u0024"));
return 0;
}
When the # operator is applied as part of the expansion of str, the \ is
doubled, producing the line:
printf (" # of <%s> is <%s>\n", "\u0024", "\"\\u0024\"");
in accordance with 6.8.3.2p2.
Now, when TP5 is reached one has to decide whether the UCN is recognised
first, generating:
printf (" # of <%s> is <%s>\n", "\u0024", "\"\$\"");
and undefined behaviour because of the escape sequence \$ - though I
would expect at least some implementations to generate:
# of <$> is <"\$">
- or else the escape sequence \\ is recognised first, generating the
output:
# of <$> is <"\u0024">
Neither, however, is what the naive programmer would expect, and neither
interpretation allows a non-basic character to remain in a string that has
the # operator applied to it.
Another serious issue with UCNs is that they do not mix well with systems
such as ISO 2022. Consider a situation where redundant shift sequences
appear within string literals in source files. In C89 these sequences will
be retained throughout the translation process and will appear when the
literal is output by the program. In C9X the characters in the literal
will be converted to UCNs and the shift sequences lost; a new set of,
possibly different, shift sequences has to be added during TP5. For
some applications this is a Quiet Change from C89.
Public Comment Number PC-____
Comment 1.
Category: Inconsistency
Committee Draft subsection: 5.1.2.2.1, 5.1.2.2.3
Title: Alternate forms of main() are not well-enough defined
Detailed description:
5.1.2.2.1 permits main() to have other implementation-defined types.
These types might not include a return type of int.
5.1.2.2.3p1 reads:
A return from the initial call to the /main/ function is equivalent
to calling the /exit/ function with the value returned by the /main/
function as its argument.[10] If the } that terminates the /main/ =20
function is reached, the termination status returned to the host
environment is unspecified.
The first sentence is clearly nonsense if the return type of main() is
not convertable to int.
Change 5.1.2.2.3p1 to:
If the return type of the /main/ function is a type compatible with
/int/, then a return from the initial call to the /main/ function is
equivalent to calling the /exit/ function with the value returned by =20
the /main/ function as its argument.[10] If the } that terminates the
/main/ function is reached, or the return type of the /main/ function is
not a type compatible with /int/, the termination status returned =20
to the host environment is unspecified.
Public Comment Number PC-UK0077
Comment 1.=20
Category: Normative change to feature
Committee Draft subsection: 6.1.2.4, 6.6.4.2, 6.6.6.1, 7.10.2.1
Title: Fix semantics of jumps in relation to VLAs
NOTICE - this is a replacement for PC-UK0045, which is withdrawn.
Detailed description:
Consider the code:
{
int n =3D 1;
label:
int v [n];
/* ... */
if (n++ < 10)
goto label;
}
The constraint on 6.6.6.1 does not forbid this jump, but the storage for
v cannot be allocated on block entry as described in 6.1.2.4p3.
Consider the code:
{
int n =3D 1;
goto label;
int v [n];
label:
/* ... */
}
This also does not violate the constraint, but the size of the array is
never determined.
Consider the code:
int n;
/* ... */
if (n > 0)
goto label;
{
n =3D 1;
label:
int v [n];
/* ... */
}
This is forbidden by 6.6.6.1, but its meaning is clear and sensible.
The intent of the constraint in 6.6.6.1 is clearly to prevent a jump into
a block from skipping a VLA declaration, but as can be seen it does not
have this effect in practice.
Similarly, the wording of 6.1.2.4p3 for VLAs is obviously an attempt to
adapt the previous wording, but it does not have the right effect.
Previous discussion within WG14 appeared to reach the conclusion that:
- jumping into the scope of a VLA should violate a constraint;
- jumping out of the scope of a VLA causes storage to no longer be
reserved, even if the block containing the declaration has not been left;
and these rules seem eminently practical. To do this:
In 6.1.2.4p3, replace:
Storage is guaranteed [...] execution of the block ends in any way.
with:
For objects that do not have a variable length array type, storage is
guaranteed to be reserved for a new instance of such an object on each
entry into the block with which it is associated; the object initially has
indeterminate value. If an initialization is specified for the value
stored in each object, it is performed each time the declaration is
reached in the execution of the block; otherwise the value becomes
indeterminate each time the declaration is reached. Storage for the
object is no longer guaranteed to be reserved when execution of the block
ends in any way. For objects that have a variable length array type,
storage is guaranteed to be reserved for a new instance of such an object
each time the declaration is reached in the execution of the program.
The initial value is indeterminate. Storage for the object is no longer
guaranteed to be reserved when execution of the program leaves the
scope of the declaration [*].
[*] Leaving the innermost block containing the declaration, or
jumping to a point in that block or an embedded block before the
declaration, leaves the scope of the declaration.
In 6.6.4.2p1, replace the first sentence with:
The controlling expression of a /switch/ statement shall have integer
type. If the /switch/ statement causes a jump to within the scope of an
identifier with variably modified type, the entire /switch/
statement shall be within the scope of that identifier [*].
[*] That is, the declaratio either preceeds the /switch/ statement,
or it occurs after the last /case/ or /default/ label that is in the block
containing the declaration and is associated with the /switch/.
In 6.6.6.1p1, replace the second sentence with:
A /goto/ statement shall not jump from outside the scope of an
identifier with variably modified type to inside the scope of that
identifier.
In 7.10.2.1, change the last sentence of paragraph 2 from:
If there has been no such invocation, or if the function containing
the invocation of the /setjmp/ macro has terminated execution [192] in the
interim, the behavior is undefined.
to:
If there has been no such invocation, or if the function containing
the invocation of the /setjmp/ macro has terminated execution [192] in the
interim, or if the invocation of the /setjmp/ macro was within the scope
of an identifier with variably modified type and execution has left that
scope in the interim, the behavior is undefined.
Public Comment Number PC-UK0078
Comment 1.=20
Category: Normative change to existing feature retaining the original inten=
t
Committee Draft subsection: 5.1.1.2, 5.2.1
Title: Universal character name handling
Detailed description:
A nasty little problem arises in code like the following:
#define str(a) #a
str("$")
In phase 1, the second line is mapped to str("\u0024") or perhaps
str("\U00000024"). In phase 4, this will be mapped to #"\u0024" and (by
6.8.3.2 The # operator paragraph 2) to "\"\\u0024\"". In phase 5,
this will be mapped to the execution character set, but there is no
explicit statement of the priority of mapping escape sequences and
universal character names. So it is probably mapped to the sequence
of characters:
'"','\\','u','0','0','2','4','"','\0'
but (if universal character names take priority) to
'"','\$','"','\0'
which leads to undefined behaviour. In either case, this is a quiet
change from C89. There are quite a lot of similar ambiguities commented
on elsewhere, that need some sort of resolution.
The more that I think about it, the less that I think the problems with
these can be solved by tweaking, so here is a radical solution that I
believe maintains all the functionality and resolves the problem. It
is based on the principle that universal character names have a similar
purpose to trigraphs and therefore should be treated similarly. I think
that the following changes are all that are NECESSARY, but some more
cleaning up may be desirable.
5.1.1.2 Translation phases
Phase 1 should be rewritten as:
1. Physical source file multibyte characters are mapped to the source
character set (introducing new-line characters for end-of-line indicators)
if necessary. Secondly, trigraph sequences are replaced by corresponding
single-character internal representations. Thirdly, universal-character-na=
mes are
replaced by the corresponding single-character internal representations.
Phase 5 should be rewritten as:
5. Each source character set member and escape sequence in character
constants and string literals is converted to a member of the execution
character set.
Footnote 6 should be rewritten as:
6. The process of handling extended characters is specified in terms of
mapping to an single-character encoding that includes the union of the
whole source character set and the characters specified by
ISO/IEC 10646-1, and, in the case of character literals and strings,
further mapping to the execution character set. In practical terms,
however, any internal encoding may be used, so long as an actual
character encountered in the input, and the same character expressed in
the input as a universal-character-name (i.e., using the \U or \u
notation), are handled equivalently.
Constraint 2 could be deleted, as it is now unnecessary.
5.2.1 Character sets
A new paragraph 6 should be added:
6. Source cha acters shall be encoded as if the source character set
included the whole of ISO/IEC 10646 as single characters, using an
unspecified mapping to integral values (except as specified
above).
Public Comment Number PC-UK0079
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.1.1.2
Title: Source line splicing
Detailed description:
One of the obscurer traps in C89 is that trailing spaces in C programs
are significant in precisely one context: following the '\' used to splice
physical source lines in translation phase 2. This causes considerable
trouble on systems that support fixed-format records, because the
implementation can treat those spaces as part of the end-of-line
indicator, but need not do so. Many implementors think that the standard
mandates trailing spaces to be regarded as significant. I suggest adding t=
he
following:
Recommended Practice
While mapping the physical source file to the source character set
during phase 1, an implementation should regard an end-of-line indicator
as being a maximal sequence of horizontal white space terminated by a
single end-of-record indicator including any associated vertical layout
directives. E.g. on a system that uses the same I/O model as C, "A \t
\n\fB\n\n\t \tC\n" should be mapped to "A\nB\n\n\t \tC\n".
Public Comment Number PC-UK0080
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.1.2
Title: Universal character names and #include
Detailed description:
I am afraid that universal character names have introduced some
incompatibilities with C89, as in directives like '#include "a$b.h"'.
This was defined in C89, but becomes undefined in C9X (i.e. it
maps to '#include "a\u0024b.h"'). This is a deceptive trap, and one that
will cause serious problems on some systems, as "$" is a fairly common
character in header names.
An evil variant of this is '#include "\udefault\a$b.h"' on MS-DOS and
derivative systems. This maps to "\udefault\a\u0024b.h", which is either
handled as such or mapped to "?ult\a$b.h", where '?' is whatever '\udefa'
is. The current wording implies that one or the other approach should be
used, though I don't think that it actually forbids mapping back to
"\udefault\a$b.h".
Note that these are quiet changes. In C89, "$" can be used in a program
as a normal character, subject ONLY to it being a member of the basic
source (and, if necessary, the basic execution) character sets.=20
In C9X, it has an implementation-defined value that need not be that of
any character. I suggest adding the following to help with the header and
pragma problems:
Whether a universal character name or character not in the the basic
source character set is interpreted during phase 4 in its universal
character name form or as a single character is implementation-defined.
Under this circumstance alone, an actual extended character encountered
in the input, and the same extended character expressed in the input as a
universal-character-name, need not be handled equivalently.
Recommended practice
An implementation should, when appropriate, interpret characters in
their input form during phase 4. A good implementation will diagnose uses
when this is not the case, or where there is potential ambiguity.
Public Comment Number PC-UK0081
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.1.2, 6.1.3.4, 6.1.4, Annex B
Title: Universal character names and character constants
Detailed description:
If both the basic source and basic execution character sets include "$"
(which is implementation-defined in both C89 and C9X), the following is
true in C89:
#include <limits.h>
#if '$' <=3D UCHAR_MAX
But this is NOT required by the current wording of paragraphs 10 and 11
in C9X, which leaves this case implementation-defined even if both the
basic source and basic execution character sets include '$'. This is
because the '$' expands to '\u0024', and the wording in those sections
makes it quite clear that '\u0024' is neither a single character nor an
escape sequence. Note that this affects ONLY translation phase 4, because
phase 5 deals with the problem.
I suggest moving "universal-character-name" in the Syntax section of
6.1.3.4 Character constants from being an entry in "c-char" to being one
in "escape-sequence". This also needs to be done in 6.1.4 String literals
and both places in Annex B, of course, but I can't see that it introduces
any problems in any of them or other sections.
Public Comment Number PC-UK0082
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.2.1
Title: Source character set values
Detailed description:
While investigating universal character names, I have realised that there
does not seem to be any requirement on the characters in the source
character set to have positive values, or even to be non-zero! 6.8.1
Conditional inclusion paragraph 3 adds a little imple mentation-definition,=
but not
much. I suggest replacing the following sentence in paragraph 3:
In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be one
greater than the value of the previous.
by:
In both the source and execution basic character sets, the value of
each character in the above list shall be strictly positive, the value of
zero shall not correspond to any printing character, and the value
of each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
Public Comment Number PC-UK0083
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 5.2.1.2
Title: Multibyte characters and C89/C9X changes
Detailed description:
This appears to be a relic of C89, as far as the source character set is
concerned, and is utterly baffling in the context of C9X. Here are some
of the problems:
1) Paragraph 1 refers to multibyte characters in the source character
set, but 5.1.1.2 bullet one refers to physical source file multibyte
characters being mapped to members of the source character
set.
2) The second bullet says that that the presence, meaning, and
representation of any additional characters is locale-specific. But
locale is an execution concept! I cannot find anything anywhere else
in the standard that describes the concept of locale during compilation.
3) The fourth bullet says that a byte with all bits zero shall be
interpreted as a null character, but the source character set is not
required to include a null character (5.2.1. paragraph 2).
4) Paragraph 2 describes how multibyte characters must fit within
various syntactic objects. But tokenisation does not occur until
translation phase 3, and multibyte characters are mapped to universal
character names in phase 1!
5) And, in any case, at what state should this be true? After phase
3, or after phase 4? Token concatenation and stringisation could cause
trouble here, especially if a multibyte character in a identifier changed
the shift state (ugh).
I suggest replacing paragraph 1 by:
1. The source may be encoded using multibyte characters, used to
represent members of the extended character set. The execution character
set may also contain multibyte characters, which need not have
the same encoding as for the source. For the execution character set,
the following shall hold:
Paragraph 2 should be replaced by:
Recommended practice
If the source is encoded using multibyte characters, a representation
compatible with some conforming multibyte execution character set should
be used.
Public Comment Number PC-UK0084
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.1.2
Title: Identifier lengths
Detailed description:
Paragraph 6 is ambiguous. Do the 31 and 63 character limits include
universal escapes as one character, or as their source length? This needs
specifying clearly, one way or the other, or there will be serious
confusion. I cannot suggest wording, as I do not know the committee's
intentions.
Public Comment Number PC-UK0085
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 5.2.2, 6.1.3.4
Title: The escape character
Detailed description:
I still don't understand why '\e' isn't provided for ESC. The answer
given in the C89 Rationale (that is is not available in EBCDIC) is quite
simply wrong - evidence available upon request. It could clearly be added
upwards compatibly but, equally clearly, its specification has to be that
it does something implementation-defined (which is precisely what ASCII
and ISO 646 say.)
Public Comment Number PC-UK0086
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.8.1
Title: Invalid but skipped pre-processor directives
Detailed description:
Programs of the following form currently cause serious arguments, and I
cannot see that the ambiguity has been resolved:
#if 0 =3D=3D 1
#axolotl
#endif
Is this permitted or is it not? I.e. is the undefined pre-processing
directive "#axolotl" an error? Most compilers assume that it should be
quietly ignored, but a few reject the above program fragment. Assuming
that it should be ignored, I suggest a footnote in 6.8.1 Conditional =20
inclusion after "the other preprocessing tokens in the group." along the
lines of:
124a Thus unrecognised preprocessing directives in a group that is
skipped are ignored and do not cause an error.
Alternatively, if it should be an error, there should be some rewording
to indicate that.
Public Comment Number PC-UK0087
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.4.4
Title: Macros for format specifiers
Detailed description:
These are all very well, but this is a major quiet change and not a
welcome one, either. In C89, long is guaranteed to be the longest integer
type, and it is possible to cast to long and use a simple format
to print any integer. C9X abolishes this, and will break many programs.
Even when they are rewritten, their formats will become unreadable. I
suggest one of two solutions:
1) Restore the requirement that long is the longest integer type
or:
2) Introduce %md, %mu, %mx etc. for the ***MAX forms to alleviate the
pain, as has been suggested. This is still a change, but should cause
less opposition.
Doing BOTH enables programmers to convert their code to using intmax_t
during the life of C9X, which leaves the option open for a future revision
of the C standard to reintroduce 'long long' with minimum incompatibility,
and is what I should prefer.
The current proposal forces immediate and serious incompatibility, breaks
existing and important conforming code, and makes it impossible to convert
it cleanly to C9X.
Public Comment Number PC-UK0088
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.13.8
Title: Direct input/output functions
Detailed description:
These have caused considerable confusion to both users and implementors
since they were introduced. What DO they do on text streams on non-Unix
systems? Experience shows that they often do something unhelpful - such
as fwrite writing files that cannot be read back in again by fread
without loss of information. Note that the problem is not in the actual
data transfer, but in the problem of how to convert an unspecified block
of storage to characters and back again.
In particular, 7.13.2 Streams states that only some sequences of
characters can be written out and read back in again - actually, there are
even more constraints than that (e.g. record lengths). Some non-Unix
implementations have converted the data to unsigned characters and then
to hexadecimal, but most just write the raw characters and let the chaos
ensue. And chaos is precisely what the programmer gets, in general.
This ambiguity has caused trouble for long enough. I suggest adding one
or other of the paragraphs:
An implementation may define that these functions are not available
for text streams. If that is the case, calling one of these functions on
a text stream shall have no effect except to set errno to an =20
implementation-defined positive value and return EOF.
or:
It is implementation-defined how the storage is converted to and from
characters for I/O to and from text streams. The implementation shall
ensure that one or more objects of any type can be written out using the
fwrite function and read back in to objects of the same type using the
fread function with the same value of size without loss of information.
Public Comment Number PC-UK0089
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.13.3
Title: Requiring line buffering on stderr
Detailed description:
Paragraph 7 is unimplementable under many systems. There are systems
that support only full buffering for some classes of file - including
Unix! Try writing stderr to fixed-block tapes on Unix systems where
write() will not reblock, for example. It is also COMPLETELY impossible
to implement under MVS, CMS and probably VMS, as buffering is an inherent
property of the type of file and cannot be changed by the connexion.
It is not reasonable to require that every single MVS implementation
ignores the C standard (even if in such a minor respect.) I suggest
changing the wording to:
... When opened, the standard error stream is not fully buffered,
except in implementation-defined circumstances where only full buffering
is available; ...
Public Comment Number PC-UK0090
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.13.5
Title: Determining whether a stream is interactive
Detailed description:
An old problem with the C library is that some essential functions in the
base document operated on Unix file descriptors and not streams. Most of
these have been added to C in 'stream' form, but isatty() has not. This
is a serious omission as it means that there is no way for a portable
program to determine whether a stream is 'interactive' or not, despite the
fact that such semantics are defined in 7.13.3 Files. The following
specification has been implemented several times, under both MVS and
Unix, and probably other systems.
I suggest adding something like the following:
7.13.5.7 The fisatty function
Synopsis
1 #include <stdio.h>
int fisatty(FILE *stream)
Description
2 The fisatty function indicates whether the stream refers to an
interactive device, in the sense used by section 7.13.3 to determine
whether a stream is opened fully buffered or not.
Returns
3 The fisatty function returns a nonzero value if and only if the
stream can be determined to refer to an interactive device.
=20
[ Incidentally, this state can change during the lifetime of a stream
under MVS and some other systems, but I suggest ignoring that little
nasty! The above wording should be adequate for both the changing and
normal cases. ]
Public Comment Number PC-UK0091
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.13.5
Title: Truncating a file
Detailed description:
A frequently missed feature of C is the ability to truncate a file; all
that the standard provides is the ability to clear a file and rewrite it
from the beginning. The following specification deliberately does
not attempt to follow any common existing practice, but is worded so that
it should be easy to implement on most important systems and requires a
near-minimal specification (so as to maintain consistency with other parts
of the standard.) I have implemented something very close to the
following specification on both MVS and Unix.
I suggest adding something like the following:
7.13.5.8 The ftruncate function
Synopsis
1 #include <stdio.h>
int ftruncate(FILE *stream)
Description
2 The ftruncate function truncates the file at the current position.
All characters in the file beyond the current position become
inaccessible, and the logical end of file is set to the current position. =
All
other properties of the file and stream are unchanged, unless an error
occurs.
3 A call to the ftruncate function is an output operation (7.13.5.3).
Returns
4 The ftruncate function returns zero if the file was successfully
runcated, or EOF if the stream was open for reading or any other rrors
were determined.
Public Comment Number PC-UK0092
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.13.9.2, 7.13.9.3, 7.13.9.5, 7.13.10.1
Title: Hard I/O errors and EOF
Detailed description:
7.13.9.2 The fseek function, 7.13.9.3 The fsetpos function, 7.13.9.5 The
rewind function and 7.13.10.1 The clearerr function all make the
assumption that the end-of-file and error indicators can be cleared,
and still have a useful specification. This is not true, even under
Unix. Consider EOF from a pipe or an I/O error from a remote socket, for
example. Furthermore, many implementations already support an enhanced
interface (described below), and some programs rely on it, so C9X should
be updated to reflect existing practice.
It is a great pity that two of them are void functions, but that cannot
be changed now, so I suggest adding the following paragraph to the first
two:
=20
If either of the end-of-file or error indicators are set, and the
implementation can determine that the condition that caused them to be
set cannot be cleared, it shall set an implementation-defined positive
value in errno and return a nonzero value.
and the following to the second two:
If either of the end-of-file or error indicators are set, and the
implementation can determine that the condition that caused them to be set
cannot be cleared, it shall set an implementation-defined positive value
in errno.
Public Comment Number PC-UK0093
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.13.10
Title: I/O error diagnosis function
Detailed description:
One of the worst aspects of programs written in standard C is that
application diagnostics are so poor, which is partly because of the
requirement for all of them to be mapped into a single integer error
code, and then back to text. Many systems can provide much more
information, and a standard function is needed so that portable
applications can make use of that. By far the most important area
is I/O, so I suggest adding the function:
7.13.10.5 The ioerror function
Synopsis
1 #include <stdio.h>
char *ioerror(FILE *stream)
Description
2 The ioerror function maps the error state of the stream to a message
string. The string may contain newline characters, may include
information that is not simply a description of the reason for
the failure, and apparently identical error states may map to different
strings.
3 The implementation shall behave as if no library function calls the
ioerror function.
Returns
4 The ioerror function returns a pointer to the string if the error
flag is set for the stream. If the error flag is not set for the stream,
it is unspecified whether a null pointer, an empty string or some =20
informative text is returned. The array pointed to shall not be modified
by the program, but may be overwritten by a subsequent call to the ioerror
function.
[ Note that I have left the message unspecified rather than
implementation defined, because the main object is to get away from fixed
error messages and allow the inclusion of dynamic data. Requiring
implementation definition would discourage this, because the message will
often be received from another system component (e.g. a socket library)
and hence be unknown to the C run-time system. I have implemented the
above specification, and can hence claim prior art! ]
Public Comment Number PC-UK0094
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.2.2
Title: The srand function
Detailed description:
The example has caused an immense amount of trouble. It is an extremely
poor generator, but several vendors have insisted on implementing it
because it is in the standard. I do NOT recommend including ANY
algorithm in the standard as, at best, it is a hostage to fortune. If
people really insist on including a particular generator, PLEASE contact
me directly (nmm1@cam.ac.uk) for comments on the algorithm. I suggest
adding the following:
Recommended practice
An implementation should provide a better random number generator,
and not use this example.
Public Comment Number PC-UK0095
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.14.6
Title: BCPL muldiv for multi-precision arithmetic
Detailed description:
The div functions have no unsigned forms, which can be a serious
inconvenience for things like radix conversion and multiple length
arithmetic (including some cryptographic algorithms.) There is also the
vexed question of whether C has to support 64-bit integers and whether it
should support 128-bit integers. It would be extremely nice for C to
enable programmers to use extended integer arithmetic, without forcing
every compiler writer to have to build it in.
Considerable experience with BCPL and other languages is that double
precision integer arithmetic can be coded efficiently in a high level
language, with the exception of two primitives. These are a NxN
-> 2N multiply and a 2N -> N,N divide (giving quotient and remainder),
most of the functionality of which can be provided by a single composite
form (i.e. NxN mod N -> N,N). BCPL had a MULDIV function, which did
something like this, but it got lost somewhere in the conversion to C,
and was replaced by the much more limited div function.
Experience with MULDIV suggests that it could be improved for this
purpose, and the improved specification is proposed here. It includes the
functionality of the div functions, so there is little point in providing
unsigned versions of those. It needs the obvious changes at the head of
this section to the descriptions of div_t, ldiv_t and lldiv_t, and the
addition of udiv_t, uldiv_t and ulldiv_t. The functions should have
specifications like the following:
7.14.6.7 The muldiv function
Synopsis
1 #include <stdlib.h>
div_t muldiv(int a, int b, int c, int base);
Description
2 The muldiv function computes the quotient and remainder of the
division of the numerator a * b + c by the denominator base; if base is
zero, the value INT_MAX+1 is used instead. The returned quotient is the
algebraic quotient with any fractional part discarded.
3 If base is negative or if the result cannot be represented, the
behaviour is undefined; otherwise quot * base + rem shall equal a * b + c.
This equality shall hold as if the expressions were calculated from
the values of quot, base, rem, a, b and c without overflow.
Returns
4 The muldiv function returns a structure of type div_t, comprising
both the quotient and the remander, as for the div function (7.14.6.2).
[ Note that the reason for allowing error conditions to lead to undefined
behaviour rather than flagging them is that this function is often needed
in the core of a computationally intensive algorithm. RSA encryption is
one example. ]
7.14.6.8 The lmuldiv function
Synopsis
1 #include <stdlib.h>
ldiv_t lmuldiv(long int a, long int b, long int c,
long int base);
Description
2 The lmuldiv function is equivalent to the muldiv functi =3Don, expect
that the arguments and the members of the returned structure (which has
type ldiv_t) all have type long int and the value used if base is zero is
LONG_MAX+1.
7.14.6.9 The llmuldiv function
Synopsis
1 #include <stdlib.h>
lldiv_t llmuldiv(long long int a, long long int b,
long long int c, long long int base);
Description
2 The llmuldiv function is equivalent to the muldiv function, expect
that the arguments and the members of the returned structure (which has
type lldiv_t) all have type long long int and the value used if base is
zero is LLONG_MAX+1.
7.14.6.10 The umuldiv function
Synopsis
1 #include <stdlib.h>
udiv_t umuldiv(unsigned int a, unsigned int b, unsigned int c,
unsigned int base);
Description
2 The umuldiv function is equivalent to the muldiv function, expect
that the arguments and the members of the returned structure (which has
type udiv_t) all have type unsigned int and the value used if base is zero
is UINT_MAX+1.
7.14.6.11 The ulmuldiv function
Synopsis
1 #include <stdlib.h>
uldiv_t ulmuldiv(unsigned long int a, unsigned long int b,
unsigned long int c, unsigned long int base);
Description
2 The ulmuldiv function is equivalent to the muldiv function, expect
that the arguments and the members of the returned structure (which has
type uldiv_t) all have type unsigned long int and the value used if base
is zero is ULONG_MAX+1.
7.14.6.11 The ullmuldiv function
Synopsis
1 #include <stdlib.h>
ulldiv_t ullmuldiv(unsigned long long int a,
unsigned long long int b, unsigned long long int c,
unsigned long long int base);
Description
2 The ullmuldiv function is equivalent to the muldiv function, expect
that the arguments and the members of the returned structure (which has
type ulldiv_t) all have type unsigned long long int and the value used if
base is zero is ULLONG_MAX+1.
Public Comment Number PC-UK0096
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.11.1.1
Title: Signal handlers and signal classes
Detailed description:
The wording of paragraph 3 is better in C9X than that in C89, but still
bears little relationship to reality. Even under Unix, returning from a
SIGINT handler is as likely to cause trouble as returning from a SIGFPE,
SIGILL or SIGSEGV one. One reason for this problem under Unix is that ANY
signal causes some system calls to be aborted, and many of those do not
provide enough information to enable them to be restarted transparently;
socket I/O is a particularly grim area in this respect, as an
aborted read() or write() does not reliably indicate how much data was
successfully transferred (see POSIX.1). This problem is one of the
reasons that Unix utilities occasionally crash with a SIGSEGV
after having trapped and recovered from another signal.
I could go into some length about consistency problems in compiled code,
even though I know only a few architectures at that level, but I can say
that the problems are getting worse and many of them are blurring the
distinction between synchronous and asynchronous signals (not that there
every has been a clear boundary). Consider the latest 'fad', for example:
multiple CPU threads of execution within a single software thread (or even
software threads), and then consider which thread should handle a
signal and what it should do about the others while doing so. These
problems often mean that it is HARDER to trap and recover from an
asynchronous signal than from one like SIGFPE (which at least has a single
associated thread).
And, lastly, there are many systems where returning from a sys tem-generate=
d signal of the SIGABRT
variety is an absolute no-no!
I suggest replacing the last sentence by the much simpler and more
general:
The implementation may define circumstances in which returning from a
signal handler leads to undefined behaviour; otherwise the program will
resume execution at the point that it was interrupted.
Public Comment Number PC-UK0097
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.2, 7.11
Title: Reliable signal handling
Detailed description:
Section 7.10.2.1 The longjmp function has removed any statement about
longjmp being supported in signal handlers. As it didn't work anyway, for
other reasons, this is a major quiet change that has no effect! But some
people will be unhappy. The following is a possible change that would
improve (though not resolve) quite a lot of the problems. It is couched
in terms of recommended practice, where an implementation is required to
say whether it follows such practice.
The handling of system-generated signals is a very nasty area indeed, and
few (if any) languages get it 'right'. Most simply opt out and leave it
undefined. Unfortunately, the specification in C89 is both extremely hard
to implement successfully (even under Unix) and is almost unusable in
portable programs because of the number of exclusions necessary to make it
implementable at all.
There have been several heated debates on comp.std.c on this. There are
some well-known problems with returning from signal handlers, but there
are as many or more with jumping out of handlers. In particular, all
updated non-volatile global variables become undefined (see the "least
requirements" section in 5.1.2.3). And I can witness that this
corresponds precisely with many or most implementations.
Lastly, and most cogently, C9X has (correctly) removed any that jumping
out of signal handlers is supported! In that sense, C9X has introduced a
major quiet change, but (as mentioned above) the facility never was
usable. This proposal defines recommended practice that restores the
functionality that was intended by C89.
This wording should be added to section 5.1.2 Execution environments to
encourage implementors to do better in a defined and consistent fashion
(thus enhancing portability), without making life impossible for them. It
should be possible to implement usefully under almost all modern systems
with reasonable signal handling (including MVS and Unix). The author has
considerable experience of precisely this area under MVS, and a fair
amount under Unix and several other systems.
Note that I am assuming that the implementation can provide signal-safe
library functions, except in cases where efficiency is critical. This can
be done on every modern architecture that I know of, with minimal overhead
(though with possible storage leaks etc.) The cases where it would be
seriously inefficient are permitted to be handled differently by the
following description.
I know that some vendors will say that implementing a safe malloc() is
hard. But I have done that. It isn't hard - it just takes thought and
care. In fact, most of the exclusion sections below are unnecessary, but
were put there to prevent an implementor from having to jump through
hoops if the system is more than usually perverse. If people want to ask
me questions directly, my Email address is nmm1@cam.ac.uk.=20
All of the following text is proposed for inclusion.
5.1.2.4 Reliable signal handling
A conforming implementation shall define whether it supports reliable
signal handling and, if so, any environment that needs to be specified
during compilation or execution or both to select that support
and how a conforming program can determine that it is executing in this
state. When such conditions are satisfied, the program will be described
as being in reliable signal mode.999
999. The least requirement on a conforming implementation is that it
defines that it does not support reliable signal handling.
The remainder of this section applies only to programs in reliable signal
mode, and defines or implementation-defines semantics for behaviour that
would otherwise be undefined. Nothing in this section changes the
validity or meaning of any strictly conforming program, or any program
not executing in reliable signal mode. A facility is supported by an
implementation if it has the effect described in this section or elsewhere
in the standard.
The behaviour of conforming programs is well-defined for signals raised
by calls to the raise and abort functions, so any reference to signals in
this section should be taken to refer to system-generated signals. An
implementation shall define any restriction on the handlig of signals
raised by calls to the raise and abort functions that is not shared by the
handling of system-generated signals.
5.1.2.4.1 Extra defined semantics
If a static storage duration variable of type volatile sig_atomic_t has a
defined value at one sequence point and is updated solely between that and
the following sequence point by being assigned defined values, then then
at all times between those sequence points (inclusively) it shall contain
one of its initial or assigned values. How many times any such
assignments occur (if at all) and in what order is unspecified. It is
implementation-defined whether static duration variables of type volatile
void * have the same consistency semantics as static duration variables of
type volatile sig_atomic_t (as describe in the previous paragraph), and
whether any special environment must be specified for this to be the case.
It is implementation-defined whether nested signals (that is signals=20
raised during the execution of a signal handler) are supported. This
support may be signal-dependent and there may be other=20
implementation-defined constraints.
It is implementation-defined whether multiple signals (that is a second
signal raised before a previous one has been ignored or its signal handler
has started executing) are supported and, if so, whether a second signal
will be suspended until after the first signal has been processed or
whether the second one will handled as a nested signal. This support may
be dependent on which signals occur and in which order, and there may be
other implementation-defined constraints.
It is implementation-defined whether signals raised during the execution
of functions registered by atexit are supported.
5.1.2.4.2 Signal sequence points
The execution of the setjmp macro after the arguments have been evaluated
shall be a special sequence point, described in this section as a signal
sequence point.
The sequence points following the evaluation of the arguments of calls to
the longjmp, signal, raise, abort or exit functions shall be signal
sequence points.
If a signal handler is called as the result of raising a signal, there
shall be a signal sequence point following the creation of the argument
list for the call to the signal handler.
If a signal handler is called as the result of raising a signal and it
returns (whether by executing a return statement or by reaching the end of
the function), then there shall be a signal sequence point immediately
following the return from the handler.
It is implementation-defined whether there are any signal sequence points
associated with a call to the system function.
An implementation shall satisfy the following conditions at a signal
sequence point:
* All the conditions for a sequence point shall be satisfied.
* Unless the signal sequence point is associated with the call to a
signal handler, all objects with static storage duration and all automatic
objects defined without the register attribute prior to the latest entry
to the function that contains the signal sequence point shall be stable
in the sense that previous evaluations are complete and subsequent
evaluations have not yet occurred.
* All signals raised as a direct consequence of executing previous code
shall have been handled, and ones raised as a direct consequence of
executing subsequent code shall not yet have had any effect on the
program. Signals raised as the result of computational exceptions are
direct consequences of executing the code, but those raised as the result
of operating on files may be indirect, except as restricted by the
following paragraph.
* All previous calls of the remove, rename, fopen, freopen, fflush and
fclose functions shall have been completed and subsequent calls shall not
have been started, and all input and output to interactive devices
required by the standard shall have taken place. The intention is that
the actions of these calls shall have been synchronised with the
environment.
5.1.2.4.3 Handling reliable signals
If a system-generated signal is raised, then any call to a signal handler
shall behave as if it were invoked by a simple call to the raise function,
except for the following:
* The call to the raise function need not correspond with a well-defined
location in the code, except as defined in 5.1.2.3 and the following
constraints.
* The values of any volatile objects updated since the previous sequence
point are indeterminate, except for static storage duration variables of
type volatile sig_atomic_t updated only by assigning defined values, and
those of type volatile void * if the implementation defines them to have
the same semantics.
* The values of any non-volatile objects updated since the previous
signal sequence point are indeterminate, including those objects and
system variables that the standard defines may be updated
by any of the library functions called since that signal sequence point.
* If any library function that returns a pointer to storage that may be
overwritten by subsequent calls (such as the getenv function, 7.14.4.4, or
the time conversion functions, 7.16.3) has been called since the previous
signal sequence point, the contents of any such storage returned by any
previous call are indeterminate.
* If any library function that uses internal storage or state (such as
the strtok function, 7.15.5.8, the multibyte character functions, 7.14.7,
or the multibyte to wide-character conversion functions, 7.19.7)
has been called since the previous signal sequence point, the contents of
any such internal storage or state are indeterminate. They may be reset
to a defined state by a call that is defined to initialise such
storage or state (e.g. by calling the strtok function with a non-null
pointer in its argument s1 or by calling the mblen function with a null
pointer in its argument s).
* If the setlocale function has been called since the previous signal
sequence point, the locale is indeterminate and the effect of calling any
library function that uses the locale is undefined. The locale may be set
to a defined state by a call to setlocale with first argument LC_ALL and
a second argument that is not NULL.
* If any of the floating-point control modes have been modified since the
previous signal sequence point, using the functions defined in 7.6 or
otherwise, the floating-point environment will be indeterminate on entry
to the handler. An implementation may define other circumstances under
which the floating-point environment is indeterminate on entry to a
signal handler. The floating-point environment may be set to a defined
state by a call to fesetenv with an argument of FE_DFL_ENV.
* If any of the floating-point control modes are modified during the
execution of a signal handler, the state of the floating-point environment
upon leaving the handler is implementation-defined and may be
defined to be indeterminate. The floating-point environment may be set
to a defined state by a call to fesetenv with an argument of FE_DFL_ENV.
* An implementation may define circumstances under which the
floating-point exception flags are indeterminate upon entry to a signal
handler.
* Upon leaving a signal handler by return or by calling the exit
function, it is implementation-defined whether the floating-point
exception flags are restored to the values that they had immediately
before the signal was raised, or whether they preserve the values that
they had immediately before leaving the signal handler.
* Upon leaving a signal handler by calling the longjmp function, it is
implementation-defined whether the floating-point exception flags are
restored to the values that they had immediately before the signal
was raised, whether they are restored to the values that they had
immediately before the setjmp macro was executed, or whether they
preserve the values that they had immediately before leaving the signal
handler.
* Upon leaving a signal handler by calling the longjmp function, the
behaviour is undefined unless the jump buffer was set up either at a time
when no signal handler was executing or earlier in the execution of signal
handler for the current signal. An implementation may define other
circumstances under which leaving a signal handler by longjmp leads to
undefined behaviour.
* If the signal function (7.11.1.1) has been called for a particular
signal since the previous signal sequence point, the signal handler for
that signal is indeterminate and the effect of raising that signal is
undefined. It may be reset by another call to the signal function for
that signal, but the return value will be indeterminate.
* The state of any file object that has been accessed other than by calls
to the ferror or feof functions since the previous signal sequence point
is indeterminate.
* If the rand or srand function (7.14.2) has been called since the
previous signal sequence point, the effect of calling the rand function
subsequently is undefined. The rand function may be reset to a
defined condition by a call to the setrand function.
* If the realloc function (7.14.3.4) has been called since the previous
signal sequence point, the state of the storage pointed to by its argument
ptr is indeterminate.
* If the atexit function (7.14.4.2) has been called since the previous
signal sequence point, it is undefined whether the function is registered.
* If a signal is raised during a call to the system function (7.14.4.5),
the behaviour is implementation-defined.
Public Comment Number PC-UK0098
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 4
Title: Compliance footnote
Detailed description:
Paragraph 3 footnote 4 is somewhat misleading, as people have pointed
out. My view is that the footnote could simply be scrapped, with benefit
all round.
Public Comment Number PC-UK0099
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.2.2.3
Title: Program termination
Detailed description:
The function main is very peculiar in several respects, and a great many
users get confused by what forms of return lead to defined behaviour. I
think that dropping off the end of main() in a hosted implementation
should be defined to behave as if it were 'return 0;', which is clearly
upwards compatible with the existing state.
A far better solution would be to require non-void functions to return
with a value, but that is more controversial.
Public Comment Number PC-UK0100
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2
Title: Cross-reference error
Detailed description:
Paragraph 2 refers to Annex H, but it should refer to Annex I.
Public Comment Number PC-UK0101
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.2
Title: Linkages of identifiers
Detailed description:
The wording of paragraph 4 is thoroughly confusing, because the
expression "the A of B becomes the A of C" is culture-dependent. In the
form of English that I am most used to, it usually means "the A
of B is copied to the A of C", and that is NOT what is meant here. I
suggest that the word "becomes" is replaced by "is taken from".
Public Comment Number PC-UK0102
Comment l
Category: Other (suggestion for deprecated practice)
Committee Draft subsection: 6.1.2.2
Title: Linkages of identifiers
Detailed description:
Linkages were one of the nastiest and least-defined aspects of K&R C;
almost every early ISO/ANSI compiler got the C89 semantics wrong in many
and varied ways. While the conformance of implementations has improved,
paragraphs 4 and 5 hide some extremely deceptive traps for the
programmer; in particular, the fact that 'extern' does not necessary
imply external linkage, even on definitions, and can even imply the
converse. A large number of these traps are there mainly to
support upwards compatibility for code written for K&R compilers that did
not allow the static keyword in declarations that were not definitions
(and so subverted the extern keyword to mean 'extern or static' in that
case.) It is clearly impossible to withdraw these facilities, but
preparing to allow an improvement in some future standard would seem wise.
I suggest adding the following after paragraph 7:
Recommended practice
Defining an identifier with the storage-class specifier extern when
it has internal linkage is deprecated. Declaring (when not defining) an
identifier with internal or external linkage and no storage-class
specifier is also deprecated. An implementation shall issue a diagnostic
but continue normal processing in such cases.
6.5.4 Function specifiers introduces a related and even nastier trap,
which is commented on elsewhere.
Public Comment Number PC-UK0103
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.2.1
Title: Array subscripting example
Detailed description:
Paragraph 2 should replace "(*(E1+(E2)))" by "(*((E1)+(E2)))", to avoid
confusion. Yes, I know that the syntactic chart makes it quite
unambiguous, but the current wording in paragraph 2 is very confusing.
Public Comment Number PC-UK0104
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.6
Title: Additive operators wording
Detailed description:
The English in the last sentences of both paragraphs 8 and 9 (the ones
beginning "Unless") is ambiguous, because the binding of "unless" and "or"
in that construction is culture-dependent! I misread it several times,
because the author uses a different dialect of English to the one I am
most accustomed to. I suggest rewording them as follows:
8 .... The behaviour is undefined if the result is used as the operand
of a unary * operator that is actually evaluated, unless either the
pointer operand and the result point to elements of the same array=20
object or the pointer operand points one past the last element of an
array object and the result points to an element of the same array object.
9 .... The behaviour is undefined unless both pointers point to
elements of or one past the last element of the same array object.
I am not entirely sure whether the first wording is needed at all,
because I cannot think of a case which it excludes that is not already
excluded by the previous sentence (not quoted.)
Public Comment Number PC-UK0105
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.5.2.1
Title: Structure and union specifiers
Detailed description:
As I understand paragraph 15, it introduces the concept of zero-sized
objects; is this deliberate? I can't see any reason why not, but it has
been carefully avoided in the past.
Public Comment Number PC-UK0106
Comment 1.=20
Category: Feature that should be removed
Committee Draft subsection: 6.5.4
Title: Function specifiers
Detailed description:
Paragraph 6 is extremely confusing, and complicates an extremely tricky
area of the standard still further, which is very likely to lead to the
sort of implementation problems that bedevilled the implementation of
linkages in early C89 compilers. The inline specifier seems to create a
new sort of linkage, but is not described in those terms. Consider the
following declarations with file scope:
inline double joe (void) { return 0.0; }
double joe (void);
joe has to have external linkage because it has not been declared to have
internal linkage (by 6.1.2.2), and is a definition, but is not an external
definition (by this section.) So precisely what is the linkage of an
inline definition? Some people believe it has no linkage, but I can find
no wording anywhere in the standard that states this explicitly.
Also, paragraphs 7 and 8 are misleading, and arguably incorrect as they
are currently worded. In particular, "A file scope declaration with
extern creates an external definition." Consider the following:
static double fred (void);
inline double fred (void) { return 0.0; }
extern double fred (void);
Unless this section can be integrated closely enough with the rest of the
standard (especially 6.1.2.2 Linkages of identifiers, 6.7 External
definitions and 6.7.1 Function definitions) to avoid most implementors
getting confused, I suggest deleting it completely.
Public Comment Number PC-UK0107
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.5.2
Title: Variably modified array declarators
Detailed description:
Forbidding the '[*]' notation at top level in function definitions isn't
exactly obvious. I suggest adding a footnote after the third sentence in
paragraph 3, such as:
103a. Thus * can be used only in function declarations that are not
function definitions (see 6.5.5.3).
Public Comment Number PC-UK0108
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.5.2
Title: Ill-definition in array declarators
Detailed description:
The current wording does not seem to exclude constructions like:
void fred (double a[*][*], double b[sizeof(a)], double c[a[1][1]],
double d[&a[1]-&a[0]]);
I cannot think of any conditions where the values of such undefined
calculations are critical to the behaviour of any strictly conforming
program, but I think that some clarification is needed. There are
two options: to define that the sizes of arrays in declarations with
function prototype scope are not evaluated, and to forbid such use. I
suggest the latter, adding the following:
An identifier with a variable length array type of unspecified size
may not be used in an expression.
[ It would be possible to relax that slightly, but I can think of no good
reason for doing so, and that restriction is short and sweet. ]
Public Comment Number PC-UK0109
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.6.6.4
Title: Constraints on the return statement
Detailed description:
Paragraph 4 appears redundant, now that plain return is restricted to
functions of type void.
Public Comment Number PC-UK0110
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.6.6.4
Title: Example of the return statement
Detailed description:
I am utterly baffled by the example. What point is it intended to
demonstrate? As it states "there is no undefined behaviour", this is a
potentially serious source of confusion.
Public Comment Number PC-UK0111
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: Clarification of function definitions
Detailed description:
The rewriting rules in paragraph 10 have caused some confusion in C89,
and will cause an increasing amount as VLAs start to be used. Consider
the following:
static double a[5];
void fred (double b[5]) {
double (*p)[5] =3D &a;
double **q =3D &b; /* This looks very odd */
p =3D &b; /* And so does this */
q =3D &a;
}
I suggest adding a footnote to paragraph 10, such as:
120a. This paragraph applies to compilation as well as execution; for
example, the type checking will use the pointer type corresponding to any
parameter specified as an array.
Public Comment Number PC-UK0112
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.1.6
Title: Symbol providing alignment of objects
Detailed description:
A somewhat heated debate on the newsgroup comp.std.c brought an
interesting omission in C89 to light, which interacts in extremely obscure
ways of some the extensions in C9X. It is impossible to write a strictly
conforming wrapper for malloc() (e.g. to store the length allocated, use
count etc.) because there is no way to discover what the alignment
requirement is! So I suggest adding the following to the macros:
ALIGN_MAX
which expands to an integer constant expression that has type size_t,
the value of which is suitable for using as the alignment of any
declarable type (i.e. that is a multiple of each value of alignment =20
needed by the processor). The macro shall be suitable for use in #if
preprocessing directives.
[ The argument for including it here (rather than <stdlib.h>) is that it
is a property of the compiled code rather than the library, and is needed
by freestanding implementations that do their own space management. ]
Public Comment Number PC-UK0113
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.4.3
Title: Ambiguity in macros for integer constants
Detailed description:
I am unsure how INT8_C(123456789) is supposed to be handled. Another
nasty one is INT32_C(123456789123456789) in an implementation with 32-bit
ints and 64-bit longs. Some clarification would be useful, especially as
regards whether any diagnostics are required. I cannot suggest wording,
as I am not sure what the committee intends.
Public Comment Number PC-UK0114
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.14.7, 7.18, 7.19
Title: Ambiguity in multibyte character functions
Detailed description:
The wording of 7.14.7 paragraph 1 is historical, and very confusing in
C9X. In particular, it implies that it may apply more generally than just
this section (i.e. to 7.18 Wide character classification and mapping
utilities <wctype.h> and 7.19 Extended multibyte and wide-character
utilities <wchar.h>). This is compounded by the fact that the latter two=
=20
do not seem to define their initial shift state (except in 7.19.7.3 and
7.19.7.4).
Some significant clarification of this point is needed, as any
misunderstanding has fairly drastic effects. I cannot suggest wording, as
I am not entirely sure what the committee intends.
Public Comment Number PC-UK0115
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.19.4.5.7
Title: Ambiguity in the wcstok function
Detailed description:
I am utterly baffled by the second sentence in paragraph 3: "If s1 is a
null pointer, the value pointed to by ptr shall match that stored by the
previous call for the same wide string; otherwise the value pointed to by
ptr is ignored." The only purpose that I can see for the ptr argument is t=
o avoid wcstok
needing internal storage, yet this sentence reintroduces the need for
internal storage to check the value of ptr! Either I have missed
something crucial, or this needs attention.
Public Comment Number PC-UK0116
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.19.7.3, 7.19.7.4
Title: Ambiguity in restartable wide/multibyte conversion functions
Detailed description:
This is not entirely clear whether each function has its own internal
mbstate_t object for the case when ps is a null pointer, or whether they
share one. I think the former, but it should be clarified.
Furthermore, it is extremely unclear whether and how the internal state
can be reset to its initial state in a defined fashion, if it has become
indeterminate or unknown.
Public Comment Number PC-UK0117
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.1.2.5
Title: Major incompatibility with C89
Detailed description:
Paragraph 3 introduces a fifth integer type, longer than long. The
current partial draft of the rationale explains why, but conveniently
ignores the major incompatibilities with C9X. There are a large
number of very important, portable, conforming programs that rely on the
fact that long is the longest integer type, and they will all be badly
broken by this change.
For example, any C89 program that needs to calculate space requirements
using a mixture of size_t and off_t (with the XPG4 or Single Unix
definitions) has little option but to convert both to unsigned
long. This is highly portable, conforming and (as far as the actual
calculations go) even strictly conforming. As this class of programs
includes an immense number of commercially important applications, from
sorting utilities to databases, it cannot be ignored.
The best solution would be to abandon 'long long' entirely. Several
vendors (such as HP) have already converted to 64-bit long on 64-bit
systems, which shows that the extra type is not actually needed.
If this approach is rejected, then it is imperative to prevent this
change being a quiet change that will break clean, portable and conforming
programs. The only solution that has been proposed is a mandatory
diagnostic for any narrowing cast to either long or unsigned long. This
clearly must include both explicit casts and implicit ones (e.g. when used
as arguments).
However, even that does not solve all of the problems. The only way for
a portable or conforming C89 program to print a size_t value is to convert
it to unsigned long, and print it using "%lu" or "%lx". This construction
is so common that it is unreasonable to break such code without comment,
and the C standard should mandate a diagnostic i at least the cases where
a format string is fixed at compilation time.
Frankly, I think that this is a horrible way to proceed, but I regard it
as completely unreasonable for C9X to break clean, portable and conforming
C89 programs without comment in the way that is being proposed.
Public Comment Number PC-UK0118
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.5.3, 6.5.3.1, 6.7.1
Title: Enhancements to restrict for optimisation
Detailed description:
I think this can be made to work, and will be of immense advantage to
many people, but there are still some very serious problems to resolve.
As the current proposal stands, I am afraid that the facility will be of
limited use for optimisation on a good many modern machines. The four most=
serious
problems that I have seen are the following, and I have included
suggestions to improve all of them.
1) Arrays have always been slightly second-class objects in C, though
C9X makes them almost into first-class ones, but this is one area that
they remain firmly second-class. For example, the term in 6.7.1 Function
definitions paragraph 10 "On entry to the function" has caused some
confusion in C89, but becomes extremely serious in the context of VLAs and
restrict. Inter alia, it means that there is no way to declare an array
parameter with bounds that can be relied on or even to guarantee that an
apparently array argument is not a null pointer.
The main reason this problem is so serious is that modern RISC CPUs are a
hundred times as fast as their memory, and an increasing number of such
architectures are introducing various forms of operand preloading to cope
with this problem. To do this efficiently, a compiler needs to know both
the declared size of an array and that it is v lid on function entry.
This can produce much better code than if it has to delay preloading until
an actual reference through the argument, and this sort of optimisation is
fairly standard in Fortran.
I believe that it is fairly easy to make restrict-qualified array
arguments safe for optimisation (though probably not debugging). It could
be done for all arguments, but there are almost certainly many
programs that rely on the fact that array bounds are not checked in C.
Yes, I know about the wording in sections 6.3.6 and elsewhere, but they
are not watertight and hence cannot be used for optimisation.
2) There is a horrible problem introduced by 6.5.3 Type qualifiers
paragraph 7, and (I am afraid) described incorrectly in 6.5.3.1 Formal
definition of restrict example 3. Consider the following variation of
that example:
extern int * s =3D NULL;
void h (int n, int * const restrict p, const int * const q,
const int * const r) {
int i;
*s =3D 0;
for (i =3D 0; i < n; ++i) *s +=3D (p[i] =3D q[i]+r[i]);
}
double a[5], b[5], c;
s =3D &c; fred(5,a,b,b);
s =3D &b[3]; fred(5,a,b,b);
Unless I am much mistaken, this is conforming. It is certainly
completely unoptimisable, unless the compiler can work out what the
contents of s are. The following example is equally bad on many
systems.
extern int func(int,int);
void h (int n, int * const restrict p, const int * const q,
const int * const r) {
int i;
for (i =3D 0; i < n; ++i) p[i] =3D func(q[i],r[i]);
}
Firstly, these examples show that plastering arguments with const does
not really help the compiler very much when it comes to optimisation,
because it doesn't prevent update through any other pointer. Secondly, it
shows that the restrict qualifier does very little to help with
indicating that immutable arrays are actually immutable - all it does say
is that a particular restrict-qualified parameter will not update another
argument.
There are two conditions actually needed for optimisation. One is that a m=
odified object is not
accessed through any other pointer, and restrict does this. The other is
to know that an unmodified object is immutable during the life of the
pointer, and the current specifications of restrict and const don't help
much. The latter can be solved by noting that there is no need to forbid
multiple accesses to restrict-qualified objects where no accesses modify
the object.
3) 6.5.3.1 Formal definition of restrict paragraph 4 refers to "the
array object that is determined dynamically by all references".
Precisely what does this mean? Consider the following code fragment - for
simplicity, assume that 'sizeof(double) > 1':
void fred (restrict double a[3], restrict double b[3]) {
((char *)b)[sizeof(double)+2] =3D ((char *)a)[sizeof(double)+1];
a[0] =3D b[2];
}
double array[3];
fred(array,array);
Obviously, I can produce far more evil examples, including ones where the
definition of the array objects depends on implementation-defined or
unspecified (but not undefined) behaviour. I am afraid that a precise
definition is needed. My proposal STILL does not handle cases like the
following very well:
void fred (restrict char *a, char *c) {
double *b =3D a;
((char *)b)[5] =3D 0;
*c =3D 1;
}
double z[10];
fred(z,&a[6]);
But that is thoroughly perverse. Yes, I know that it is both legal and
common, but my view is that such code is beyond hope and I don't care if
it runs like a drain. The best that we can hope for is to prevent it from
causing syntactic or semantic problems, which the current wording does
not.
4) Consider the following:
extern volatile int fred;
void joe (const int * const volatile restrict a) {...}
joe(&fred);
Unless I have lost my marbles, that destroys the whole point of restrict.
The question is whether it is worth bothering about. My view is probably
not, on the grounds that C does not protect the fool from his folly, but
it is debatable. It could be locked out very easily.
The following are my suggestions to improve these problems. I don't
guarantee that they are watertight, but they are as good as I can make
them.
6.5.3 Type qualifiers.
The constraint is a change from the approach taken in C89, and one that
prevents several very important optimisations. So paragraph 2 should be
changed to:
2 Types other than array types in function declarations or pointer
types derived from object or incomplete types shall not be restrict
qualified.
If the combination of restrict and volatile were to be locked out, the
following could be added:
No type shall be both restrict and volatile qualified.
The following should be added to the end of the second sentence of
paragraph 7:
..., except in the case where no reference modifies any part of the
object.
6.5.3.1 Formal definition of restrict
We need to produce a precise definition of the object A. Also, in order
to allow preloading, we need to make array bounds binding. There is some
wording in 6.3.6 Additive operators paragraph 8, but I don't think that it
is sufficient for this purpose. So, add after paragraph 3:
The array object A determined dynamically by references though a
pointer object P of type T * is defined in the following way. Firstly
ignore all qualifications in T * and, if T * then becomes void *,
treat P as if T * were unsigned char *. Then, consider all pointer
expressions E based on P evaluated during the execution of B, convert them
to unsigned char *, and denote the smallest such value by Q and the
largest R. If an object is accessed, then Q and R are calculated as if
each byte of the object and the byte immediately following the end of the
object were addressed by separate pointer expressions of type unsigned
char *. Lastly, let M and N be the largest and smallest integers, such
that (unsigned char *)&P[M] <=3D (unsigned char *)Q and (unsigned char
*)&P[N] >=3D (unsigned char *)R. If either M or N is not defined because
one of (unsigned char *)&P[M] and (unsigned char *)&P[N]-1 would be
outside the limits of the originally allocated object into which P
points, the behaviour is undefined.
If P is declared as a pointer parameter, A is the array with element
type T and size N-M whose first element has address &P[M]. If P is
declared as an incomplete array parameter and M is less than 0, the
behaviour is undefined; otherwise A is the array with element type T and
size N whose first element has address &P[0]. If P is declared as a a
complete array parameter (whether variable modified or not) of size S and
M is less than 0 or N is greater than S, the behaviour is undefined;
otherwise A is the array with element type T and size S whose first
element has address &P[0].
The second sentence of paragraph 4 should be changed to:
Then either all references to values of A shall be through pointer
xpressions based on P, or no reference to A (through expressions based on
P or otherwise) shall modify any part of its contents during the execution
of B.
Example 3 should then become:
void h (int n, int * p, const int * restrict q,
const int * restrict r) {
int i;
for (i =3D 0; i < n; ++i) p[i] =3D q[i]+r[i];
}
shows how const can be used in conjunction with restrict. The const
qualifiers imply, without the need to examine the body of h, that the
values of any object accessed through q and r cannot change during the
execution of h. This is the precise assertion needed to optimise the
loop. Note that p does not need to be restrict qualified in this example,
but may allow better optimisation in a more complicated function.
6.7.1 Function definitions
The other requirement for preloading is to know that an argument is not a
null pointer. The following should be added after paragraph 9:
9 Upon entry to a function, if the actual argument corresponding to a
restrict qualified array parameter is a null pointer, the behaviour is
undefined.
Public Comment Number PC-UK0119
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 5.2.4.2.2
Title: Ambiguity in specification of FLT_ROUNDS
Detailed description:
There is a slight ambiguity in that it is not actually stated whether
FLT_ROUNDS can be set by the programmer directly (i.e. by assigning a
value to it). And, as its value can be changed, this is confusing. I
suggest adding to the beginning of paragraph 5 something like:
FLT_ROUNDS shall expand to an expression that evaluates to the
current value of the rounding mode. If FLT_ROUNDS is used in a context
where a lvalue is required, the behaviour is undefined.
Public Comment Number PC-UK0120
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.2.4.2.2
Title: Rounding in ambiguous cases without IEEE
Detailed description:
Paragraph 5 doesn't define precisely what the rounding mode terms mean,
and there are many possible interpretations (especially of nearest
rounding for numbers that fall precisely between two values.)=20
Note that this is specified by IEEE 754 but explicitly not by LIA-1. I
suggest adding the following to the end of the last sentence:
Unless __STD_IEC_559__ is defined (see Annex F), the exact meaning of
these rounding modes is implementation-defined.
Public Comment Number PC-UK0121
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.1.2.8.2
Title: Multiple integer representations and precision
Detailed description:
There is a very nasty trap here, that interacts badly with 6.2.1
Arithmetic operands and other parts of the standard. The wording does not
require all integers to use the same representation which is, I suppose,
reasonable. I haven't worked out all the consequences, and am not sure
that I want to, but I think that the current wording is a hostage to
fortune. For example:
1) What does 'precision' mean in 6.2.1.1 Characters and integers, for
two types of the same size but different representations?
2) Consider the problem of converting 0x8000 between twos' complement
and signed magnitude (in both directions).
Frankly, I don't see how to resolve this simply, except by requiring an
implementation to use the same representation for all integer data types.
But that is not a trivial restriction. However, SOMETHING must be said
about this problem.
Public Comment Number PC-UK0122
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.1.2.8.2
Title: Problems with multiple zero representations etc.
Detailed description:
The current wording forbids the all-ones representation in ones'
complement and negative zero in signed magnitude from being trap values.
This compounds the original K&R mistake of assuming that integer overflow
is ignored, and is slightly in conflict with the stated intention of IEEE
754. But there is a MUCH more serious problem and it is a major quiet
change (as the wording stands at present).
Return and initial values of zero and unspecified non-zero are defined
throughout the standard, but the standard now defines two forms of zero
for signed magnitude and ones' complement, which causes serious ambiguity
and conflicts. For example, standard practice to test whether a set of
bits is set is (value&mask)!=3D0, which will no longer work! So I suggest
changing the descriptions of the sign bit to the following:
- the corresponding value with sign bit zero is negated, and it is
implementation-defined whether the value with sign bit one and all other
bits zero is a trap value or has a value of zero;
- the sign bit has value -2N, and it is implementation-defined
whether he value with sign bit one and all other bits zero is a trap value
or has a value of -2N;
- the sign bit has value 1-2N, and it is implementation-defined
whether the value with all bits one (including the sign bit) is a trap
value or has a value of zero.
When other sections of this standard requires a value to be
initialised to zero, a function call to return zero or an expression to
evaluate to zero, the implementation shall use the value consisting of
all bits zero. When they require a function call to return non-zero or
an expression to evaluate to non-zero, the implementation shall not use
any of the values that may be trap values, whether the implementation has
defined them to be trap values or not.
Public Comment Number PC-UK0123
Comment 1.=20
Category: Feature that should be removed
Committee Draft subsection: 6.1.3.1
Title: Hexadecimal floating-point constants
Detailed description:
I can see no good reason for hexadecimal ones and, yes, I do write
special functions! It isn't needed for correct rounding, as there are
known, acceptably efficient algorithms for doing this for other bases
(and have been for 30 years and more.) Admittedly, the worst case is
O(N^2) in the size of the value (exponent and all), but that case can be
made extremely rare by fairly simple coding.
On the other hand, it would be EXTREMELY useful to be able to specify the
exact bits in a defined fashion (clearly with an implementation-defined
meaning), because that would enable a program to create peculiar values
(NaNs, infinities etc.) without playing unspeakable tricks with punning.
The current specification is of little or no use with this.
Public Comment Number PC-UK0124
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 6.2.1.3
Title: Floating to integer conversion
Detailed description:
Paragraph 1 is ambiguous, because there are two standard (i.e.
mathematical) definitions of the fractional part of negative numbers. I
suggest changing the wording to:
..., the fractional part is discarded (i.e. the number is truncated
towards zero.)
Public Comment Number PC-UK0125
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.8, F.7.5
Title: Initialisation to zero
Detailed description:
Section 6.5.8 paragraph 10 requires initialization to zero for arithmetic
types, but IEEE 754 has more than one zero, and there is the problem
mentioned under 6.1.2.8.2 Integer types. This is a consequence of the
ambiguity in C89 over whether arithmetic objects were initialised to a
value of zero or all bits zero. I don't THINK that there is any way to
distinguish two null pointers in a conforming program, unless conversions
of a null pointer to an integer give more than one representation of zero.
I can see nothing that requires all initialisations to use the same
value, though this is implied by C89 and assumed by a great many existing
programs. It would be a major quiet change to allow initialisations to
different, distinguishable values of zero or null pointers. I suggest
adding the following to 6.5.8:
If there is more than one possible representation of a null pointer
or a zero for a particular type and the representations can be
distinguished by a conforming program, the implementation shall use one =
=20
value for all implicit initialisations of objects of that type, including
subobjects of that type within unions, structures or arrays.
And the following to F.7.5:
3 The value of zero used for implicit initialization shall be the
positive zero.
Public Comment Number PC-UK0126
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.6
Title: Which functions can raise floating-point exceptions
Detailed description:
The third item of paragraph 2 is not determinable by the programmer on
some architectures, and will cause serious problems. Many systems use
floating-point for some integer operations or handle some integer
exceptions as floating-point - e.g. dividing by zero usually raises
SIGFPE, and integer multiplication or division may actually be done by
converting to floating-point and back again. I suggest replacing that
item by:
- any function call defined in the header <math.h> or defined
elsewhere with a floating-point parameter or result is assumed to have the
potential for raising floating-point exceptions, unless the documentation
promises otherwise.
This requires most of the functions in <stdlib.h> to handle exceptions
themselves, if they use floating-point, but that is implied by the
previous wording. It has the merit of at least being determinable, which
the existing wording isn't.
Public Comment Number PC-UK0127
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.6
Title: Type of fexcept_t
Detailed description:
Paragraph 4 does not specify that fexcepts_t must be an integer type, but
paragraph 5 describes its values in terms of integer (i.e. logical)
operations. I suggest changing "represents" in paragraph 4 to "is an
integer type that represents".
Public Comment Number PC-UK0128
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.6.2
Title: Floating-point exception values
Detailed description:
This does not make it clear whether zero is a permitted argument. It
needs clarification. I suggest changing the wording to:
... and can be zero or constructed by bitwise ORs ...
Public Comment Number PC-UK0129
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.6
Title: Failure when handling exception flags
Detailed description:
These specifications do not allow the implementation any way to indicate
failure. This is adequate for strict IEEE arithmetic, but is a hostage to
fortune and prevents their use for several IEEE-like arithmetics. All
such implementations can do is to not define the macros, thus implying
that they cannot support the functions, whereas they may be able to
support all reasonable use of the functions and merely fail in some
perverse circumstances.
One actual example of this is that they are often not fully resettable in
signal handlers, because the return from the handler may reset them to the
values they had on entry! It would be reasonable for an implementation to
make these functions fail when called within such a handler, as I have
done when implementing similar functions under such circumstances, but the
current wording does not permit this.
I think that they should all be integer-valued functions, and return an
error indicator.
Public Comment Number PC-UK0130
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.6.3.1
Title: fegetround and non-standard rounding modes
Detailed description:
What happens if the rounding mode is none of the ones defined above? I
suggest adding to the end of paragraph 3:
If the rounding mode does not match a rounding direction macro, an
implementation-defined negative value is returned.
Public Comment Number PC-UK0131
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.6.3.2, 7.6.4.2
Title: fesetround and feholdexcept return values
Detailed description:
Was it REALLY intended that non-zero indicates success and zero indicates
failure? If so, these are unlike most other functions in the library.
Public Comment Number PC-UK0132
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.6.3.2
Title: Obscure wording in fesetround
Detailed description:
What happens if its argument uses one form of zero where a macro expands
to another form of zero (see 6.1.2.8.2 Integer types)? It uses the term
"match", which is not defined elsewhere and could mean either numeric
equality or representational equality. I suggest changing "does not
match" to "is not equal to".
Public Comment Number PC-UK0133
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.6.3.2
Title: fesetround is often unimplementable
Detailed description:
Many existing C <math.h> implementations and even more numerical
libraries have the property that they rely on the rounding mode they are
called with being the one they were built for. To use a different
rounding mode, the user must link with a separate library. The standard
should permit an implementation to reject a change if the change is
impossible, as distinct from when it does not support that mode at all. I
suggest that paragraph 3 be reworded as:
3 The fsetround function returns a nonzero value if and only if the
requested rounding direction has been established. It shall return zero
if the direction does not match a rounding direction macro or in=20
other implementation-defined circumstances.
Public Comment Number PC-UK0134
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.6.4.1, 7.6.4.3, 7.6.4.4
Title: fegetenv, fesetenv and feupdateenv are often unimplementable
Detailed description:
These are unimplementable on many systems without system privilege (and
sometimes not even then). While most systems that have the concept of a
floating-point environment allow it to be interrogated, many do not allow
it to be set to an arbitrary state by unprivileged code. Note that this
differs from the exception flags, which are almost invariably resettable
when they exist (though even that is not guaranteed.)
I suggest changing the return type from void to int in all three of
these, and adding the following paragraph (with the obvious variations):
Returns
The fe...env function returns zero if and only the floating-point
environment was successfully stored/installed.
Public Comment Number PC-UK0135
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.6.4.2
Title: feholdexcept is sometimes unimplementable
Detailed description:
This is unimplementable on some hardware. For example, it requires the
continuation after the invalid exception, when continuing after underflow
is wanted, even on systems that distinguish the various levels of
exception. And, yes, there are systems where continuing after underflow
is possible but not after invalid - I manage one!
From=20both the software engineering and implementability point of view,
this needs an extra argument specifying the minimum set of exceptions to
mask. I suggest making the changes:
#include <fenv.h>
int feholdexcept(fenv_p *envp, int excepts);
..., and installs a non-stop (continue on exceptions) mode, if
available, for a implementation-defined set of exceptions that includes
all those specified in the parameter excepts.
Public Comment Number PC-UK0136
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7
Title: Obscure wording about constant arithmetic
Detailed description:
Paragraph 4 is extremely unclear. How can a constant overflow? Yes, I
see what this is trying to get at, but this is not how to phrase it. I
suggest the wording:
..., if available. If such a value is not available, it shall be a
constraint error to use the value of the macro INFINITY as a value of type
float.
Public Comment Number PC-UK0137
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.7
Title: Allow infinities and NaNs for each precision
Detailed description:
A major flaw in paragraphs 4 and 5 is that there is no way of specifying
an infinity or a NaN for double or long double, unless float supports
them. While this is the common case, C9X does not require it and it is
not reasonable to do so. I can see no good reason not to have three
symbols for each, exactly as for HUGE_VAL. I suggest changing 'float' to
'double' in paragraph 4 and adding the following:
The macros
INFINITY_F
INFINITY_L
are respectively float and long double analogs of INFINITY.
and changing 'float' to 'double' in paragraph 5 and adding the following:
The macros
NAN_F
NAN_L
are respectively float and long double analogs of NAN.
Public Comment Number PC-UK0138
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.7, F.2.1, F.3
Title: Provide IEC 559 required support for signalling NaNs
Detailed description:
Section 7.7 paragraphs 5 and 6 are seriously incompatible with the spirit
of IEEE 754, and could be regarded as being in breach of the letter of
IEEE 754 section 6.2, by not providing any way to define a signalling NaN
or test for whether a NaN is signalling or quiet. Furthermore, the
current C9X situation does not allow a programmer to initialise his data
to signalling NaNs (as recommended by IEEE 754). At the very least, there
should be a macro SIGNAN for creating one and a macro FP_SIGNAN for
flagging one, so I suggest adding:
4a The macro
SIGNAN
is defined if and only if the implementation supports signalling NaNs
for the double type. It expands to a constant expression of type double
representing an implementation-defined signalling NaN.
The macros
SIGNAN_F
SIGNAN_L
are respectively float and long double analogs of SIGNAN.
and adding FP_SIGNAN to paragraph 6, which makes it conform with IEEE
754. This should be done even if SIGNAN is not added.
Assuming that the nan function is removed (see 7.7.11.2 The nan
function), F.2.1 paragraph 1 needs replacing by::
The NAN, NAN_F, NAN_L, SIGNAN, SIGNAN_F, SIGNAN_L, INFINITY,
INFINITY_F and INFINITY_L macros in <math.h> provide designations for IEC
559 NaNs and infinities. The only support for signalling NaNs required by
this standard is that the fpclassify function (7.7.3.1) shall
classify them correctly. An implementation shall define the macros
SIGNAN, SIGNAN_F and SIGNAN_L only if those values are supported
compatibly with IEC 559.
In F.3 the last paragraph (starting "The signbit macro") should be
simplified by the omission of the exclusion in brackets.
Public Comment Number PC-UK0139
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7
Title: Ambiguity in specification of FP_FAST_FMA
Detailed description:
Paragraph 7 implies that FP_FAST_FMA should not be set if fma(x,y,z) is
significantly faster than x*y+z! I suggest changing "about as fast" to
"about as fast or faster".
Public Comment Number PC-UK0140
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.7
Title: What does "supported by conversion" mean?
Detailed description:
Paragraph 9 is thoroughly confusing. What does "supported by conversion"
actually mean? Does it mean the maximum number of digits that will be
produced, a limit above which a conversion will fail or the maximum
number that are guaranteed to be accurate? Paragraph 10 footnote 171
implies the last, but does not exclude either of the first two, in
conjunction. And there ARE systems where printf("%.30f",1.0/3.0) produces
0.333333333333333330000000000000. I cannot suggest wording, as
I do not know what the committee intends, but this facility is too vague
to be useful as it stands..
Public Comment Number PC-UK0141
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.7.1
Title: Which <math.h> functions can set errno
Detailed description:
C89 was and C9X is unclear about whether tan() and similar functions are
allowed to set errno or not. Its specification has no reference to a
domain error and therefore, by implication, it has no reference to
errno. By 7.1.4 paragraph 3, it is therefore allowed to set errno at
whim. But is this so? Furthermore, there are several implications in C9X
that the handling of IEEE exception flags and errno have similar
properties, so this becomes even more of a trap. I suggest adding the
following wording to the end of paragraph 1:
This section documents the use of errno by all the functions defined
in the header <math.h>, which therefore will set errno only when an error
is detected (see 7.1.4).
Public Comment Number PC-UK0142
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.7.1
Title: Extraordinary roundoff error
Detailed description:
I have no idea what "without extraordinary roundoff error" means. If
such a term is to be included, I suggest adding the following:
1 If a function produces a range error to avoid extraordinary roundoff
error, the implementation shall define the conditions when this may occur.
Public Comment Number PC-UK0143
Comment 1.=20
Category: Other (conflict with IEEE 754, LIA-1 and LIA-2)
Committee Draft subsection: 7.7.1
Title: <math.h> and floating-point signals
Detailed description:
This STILL forbids an implementation from trapping bad arguments to the
mathematical functions, even if the user wants such a trap. I have had
dozens of users horrified when I have told them that the C standard
REQUIRES implementations to produce wrong answers without a trap, and
sometimes without even an error flag.
It is in obvious conflict with the stated intention of IEEE 754 and
LIA-1, and actually prevents an implementation from conforming to both C9X
and the proposed LIA-2 simultaneously. Despite this, H.3.1.2 Paragraph 1
claims that the C standard allows "hard to ignore" trapping and
diagnostics as an alternative form of notification (as required by LIA-1),
but it specifically FORBIDS this in many routines of the library (e.g.
<math.h>).
I suggest adding the following:
4 An implementation shall provide a mechanism for programs to be
executed as described above. It may also provide a mechanism by which
programs are executed in a mode in which some or all domain and range
errors raise signals in an implementation-defined fashion.
Recommended practice
If domain errors raise a signal, the signal should be SIGILL. If
range errors raise a signal, the signal should be SIGFPE. It should be
possible for the program to run in a mode where domain errors and range
errors that correspond to overflow raise signals, but range errors that
correspond to underflow do not.
Alternatively, people might prefer to use SIGFPE for both classes of
error; there are arguments both ways, and either choice is reasonable.
If this change is not made, H.3.1.2 should be corrected.
Public Comment Number PC-UK0144
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.7.3.2
Title: Serious confusion in the signbit macro
Detailed description:
The wording of this is seriously flawed. It says that it returns the
sign of a number, but is clearly intended to test the sign bit, and these
are NOT equivalent. IEEE 754 states explicitly that it does not
use the sign bit of NaNs as a sign bit, and all VAX NaNs have sign bit
zero (the equivalents with sign bit one are invalid numbers and not NaNs.)
And there is nowhere else in C9X that requires the sign of a
floating-point number to be held as a bit - surely people have not yet
forgotten ones' and twos' complement floating point? I suggest replacing
paragraphs 2 and 3 and footnote 175 by:
2a For valid non-zero values (including infinities but not NaNs), the
signbit macro returns nonzero if and only if the sign of its argument is
negative.
2b For zeroes and NaNs when __STD_IEC_559__ is defined, the signbit
macro returns nonzero if and only the sign bit of the value is set.
2c For zeroes and NaNs when __STD_IEC_559__ is not defined, the signbit ma=
cro returns nonzero
for an implementation-defined set of values and zero otherwise.
Public Comment Number PC-UK0145
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.7, 7.7.6.14
Title: Efficiency of the ilogb function
Detailed description:
I am distinctly unhappy with this. As a person who has written portable
special function code (including things like sin/cos), I badly needed
something like this to localise the system dependencies. But NOT this
specification, on the grounds of severe inefficiency. There are two
reasonable approaches, and C9X has fallen between them:
1) To have a composite function that returns the type of value, its
sign and (only if it is finite and non-zero) its exponent and mantissa.
2) To have separate functions for each level of classification, with
later ones being defined only for appropriate arguments.
I suggest simply dropping the requirements to return particular values
for zero, infinities and NaNs - i.e. remove the text "; it computes the
value FP_ILOGB0 ... if x is a NaN", and scrapping 7.7 Mathematics <math.h>
paragraph 8 entirely. This could be implemented a lot more efficiently
and hence would be vastly more useful. It remains compatible with LIA-1
exponentF.
Public Comment Number PC-UK0146
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.7.10.3
Title: The remquo function is confusing and hard to implement
Detailed description:
This will be extremely hard to implement on many architectures, will be a
fruitful source of obscure bugs, and will baffle most users. It also
creates havoc in 7.9.1 Type-generic macros. I suggest making the quo
argument 'double *' and replacing the last sentence by:
In the object pointed to by quo it stores the remainder as defined
under the remainder function (see 7.7.10.2).
If this is not done, it needs to be excluded from the list of
type-generic macros in 7.9.1.
Public Comment Number PC-UK0147
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.7.11.1
Title: Ambiguity in the copysign function
Detailed description:
What does "treat negative zero consistently" mean? Does IBM 370
arithmetic do it? Does VAX? Does Intel? Does IEEE? I suggest replacing
the sentence "On implementations ... the sign of zero as positive." by
Unless __STD_IEC_559__ is defined (see Annex F), it is
implementation-defined whether any representations of zero are regarded as
negative by this function and, if so, which.
Public Comment Number PC-UK0148
Comment 1.=20
Category: Feature that should be removed
Committee Draft subsection: 7.7.11.2
Title: The nan() function seems pointless and confusing
Detailed description:
This implies that the NaN macro takes a string argument, which is
incompatible with its use in 7.7 Mathematics. Given the statement in IEEE
754 that only one NaN of each type need be provided, and the absence of
facilities for handling different NaN values both in IEEE 754 and C9X, I
suggest scrapping this function entirely.
Public Comment Number PC-UK0149
Comment 1.=20
Category: Feature that should be removed
Committee Draft subsection: 7.7.11.4
Title: nextafterx() seems pointless and confusing
Detailed description:
Why is this provided? Footnote 181 seems to be intended to explain, but
I find it even more baffling than the function specification. It is also
very unclear how it should be handled by 7.9.1 Type-generic macros
paragraph 5. If this function isn't critical, I suggest scrapping it entir=
ely.
If this is not done, it needs to be excluded from the list of
type-generic macros in 7.9.1.
Public Comment Number PC-UK0150
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.7.12.2, 7.7.12.3, F.9.9.2, F.9.9.3
Title: Mathematically incorrect behaviour of fmax/fmin
Detailed description:
7.7.12.2 and 7.7.12.3 footnotes 182 and 183 should be scrapped. They are
mathematically incorrect, as IEEE 754 uses NaNs as an error indicator and
NOT a missing value indicator, and are an unreasonable restriction on
non-IEEE implementations.
The specification of these in F.9.9.2 and F.9.9.3 is mathematically
incompatible with IEEE 754's use of NaNs. Furthermore, the example code
given does not raise the invalid exception if an argument is a NaN. The
combination of these provides a very serious impact on robustness. I
suggest changing the wording to:
1 - If either argument is a NaN then fmax returns one of its
argument NaNs; it is unspecified whether the invalid exception will be
raised.
The body of the fmax function might be
{ return (isgreaterequal(x,y) ? x : y); }
7.8.2 Complex functions
=3D Comment numeric-28 =3D
Public Comment Number PC-UK0151
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 7.8.2
Title: Why mention degrees versus radians?
Detailed description:
Why does paragraph 1 need to mention the radian versus degree problem?
Because it is specified here but not in 7.7.4 Trigonometric functions, it
could be interpreted as saying the former MAY be implemented using
degrees! I suggest either dropping it or copying it to 7.7.4.
Public Comment Number PC-UK0152
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.8.2
Title: Error handling for complex functions
Detailed description:
Why does C9X specifically suggest that implementations need not bother
with domain and range error handling for complex functions? This makes it
quite impossible to use these functions in portable code if robustness is
of any importance. The argument that they may need to be implemented
inline doesn't hold water, as the same applies to the real functions.
Note that domain errors CAN occur for the carg function and range errors
for many of them. I suggest replacing paragraph 1 by:
1 The error handling for domain errors is as specified in section 7.7.1.
2 A overflowing range error occurs if the mathematical result of the
function has either or both of its real and imaginary components that
cannot be represented in an object of the specified type, without =20
extraordinary roundoff error, because at least one is finite but too
large. On an overflowing range error, it is implementation-defined
whether the function returns an implementation-defined value for
both components, or only those that cannot be represented; whether the
integer expression errno acquires the value ERANGE is
implementation-defined.
3 A underflowing range error occurs if the mathematical result of the
function has real and imaginary components that cannot be represented in
an object of the specified type, without extraordinary roundoff error,
because at least one is finite but too small and the other is either
finite but too small or zero. On an underflowing range error, the
function returns a value of which both the real and imaginary components
have magnitude no greater than the smallest positive real number in
the specified type and are otherwise implementation-defined; whether the
integer expression errno acquires the value ERANGE is
implementation-defined.
3 An implementation may define other circumstances under which domain
and range errors may occur.
Recommended practice
The error handling for complex functions should be as consistent with
the real mathematical functions as possible, subject to the essential
differences between the real and complex domains. In particular, the case
where one component underflows or overflows but the other does not should
be handled in a mathematically consistent fashion.
Public Comment Number PC-UK0153
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.8.2.19
Title: carg() is undefined for a complex zero
Detailed description:
This is mathematically undefined for complex zeroes. I suggest adding "A
domain error occurs if the argument is a complex zero."
Public Comment Number PC-UK0154
Comment 1.=20
Category: Feature that should be removed
Committee Draft subsection: 7.8.2.22
Title: Is the cproj function useful?
Detailed description:
Isn't this a little esoteric? Why not simply drop it, as it is pretty
easy to provide efficiently using the other functions and macros?
Public Comment Number PC-UK0155
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: Annex F
Title: The status of __STD_IEC_559_COMPLEX__
Detailed description:
There is a trap introduced by 7.8 Complex arithmetic, but it should be
fixed here. The current specification allows an implementation to define
__STD_IEC_559_COMPLEX__, but to do something completely incompatible, and
STILL claim conformance because Annex G is merely informative! I
suggest putting some wording in the introduction of Annex F like:
An implementation that defines __STD_IEC_559_COMPLEX__ shall
implement Annex G as if it were normative.
Public Comment Number PC-UK0156
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: Annex F
Title: Permitting diagnostics for uncleared exception flags
Detailed description:
One of the assumptions in the IEEE 754 model is that exception flags will
eventually be either cleared or diagnosed, and this is required by LIA-1.
Fortran does not specify what may be written to 'standard error', but C
does, and many vendors regard the standard as forbidding them from
issuing diagnostic in this case. H.3.1.1 Indicators states that C
permits an implementation to do this, but provides no hint as to how.
I suggest adding the following:
If any of the exception flags are set on normal termination after all
calls to functions registered by the atexit function have been made (see
7.14.4.3), and stderr is still open, the implementation may write some
diagnostics indicating the fact to stderr.
If this is NOT done, then H.3.1.1 should be corrected, or clarified to
explain how such a diagnostic can be produced.
Public Comment Number PC-UK0157
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: F.7.4
Title: Constant expressions and IEEE
Detailed description:
Hmm. I can't see any major problem with this, except that it is a bit
confusing. Consider the following:
static double fred[(int)7.5];
This section does NOT actually require that case to be evaluated during
execution, but could it be made a bit clearer?
Public Comment Number PC-UK0158
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: F.9
Title: Floating-point exception flags and errno
Detailed description:
Paragraph 4 is seriously incompatible with the spirit of IEEE 754 and the
wording of LIA-1, and actually prevents an implementation from conforming
to both C9X and the proposed LIA-2 simultaneously, for those functions
that are not specifically mentioned in this annex. I suggest changing its
wording to:
4 The invalid exception will be raised whenever errno is set to EDOM.
Subsequent subclauses of this annex specify other circumstances when the
invalid or divide-by-zero exceptions are required to be raised.
There is also a possible ambiguity in paragraphs 5 and 6, and a problem
caused by cases where the implementation may define extra range errors as
permitted by 7.7.1 Treatment of error conditions paragraph 2 (e.g.
cos(1.0e50)), that is a nasty conflict with LIA-2. It should be closed
by adding the following:
6a Whenever errno is set to ERANGE, at least one of the invalid,
divide-by-zero, overflow or underflow exceptions shall be raised.
Public Comment Number PC-UK0159
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: F.9.1.4
Title: atan2(+-0,+-0) and IEEE
Detailed description:
Defining atan2(+-0,+-0) to return a finite value and not raise the
invalid exception is mathematically incorrect, incompatible with robust
code and the wording of LIA-1, and actually prevents an implementation
from conforming to both C9X and the proposed LIA-2 simultaneously. I
suggest changing these cases to do the correct thing:
atan2(+-0,+-0) returns a NaN and raises the invalid exception.
Public Comment Number PC-UK0160
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: F.9.3.4
Title: Inconsistent wording in frexp
Detailed description:
This uses the words 'returns' and 'stores' for its second argument; they
should really be made consistent.
Public Comment Number PC-UK0161
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: F.9.4.3
Title: pow(+-inf,+-0) or pow(NaN,+-0) and IEEE
Detailed description:
Defining pow(+-inf,+-0) and pow(NaN,+-0) to return a finite value and not
raise the invalid exception is mathematically incorrect and incompatible
with robust code. I suggest changing these cases to do the correct thing:
pow(+-inf,+-0) returns a NaN and raises the invalid exception.
pow(NaN,+-0) returns its NaN argument.
Public Comment Number PC-UK0162
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.2.1.6
Title: Complex infinities and NaNs
Detailed description:
This is seriously incompatible with the spirit of IEEE 754 and LIA-1, in
that information can be lost without flagging the fact in any way. Far
worse, it REQUIRES complex infinities and NaNs to be converted to finite
numbers with no indication of the fact. This is not reasonable. I
suggest changing 6.2.1.6 paragraph 2 to say:
1 When a value of complex type both of whose components are finite real
numbers is converted to a real type, the imaginary part of the complex
value is discarded and the value of the real part is converted according
to the conversion rules for the corresponding real type. When a value of
complex type either of whose components is an infinity or a NaN is
converted to a real type, the result is implementation-defined.
And adding the following:
Recommended practice
If the implementation supports the concept of complex infinities, the
result of converting a real infinity to a complex type should be a complex
infinity and that of converting a complex infinity to a real type should
be a positive infinity. If the implementation supports the concept of
complex NaNs, the result of converting a real NaN to a complex type should
be a complex NaN and that of converting a complex NaN to a real type
should be a NaN.
[ Note that conversion WITHOUT raising exceptions is provided by the
creal and cimag functions, so this is not a restriction. ]
Public Comment Number PC-UK0163
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: Annex G, G.3
Title: Imaginary, complex infinities, NaNs and inexact
Detailed description:
The concept of a complex infinity is introduced under G.4.1
Multiplicative operators, which is bizarre. It should be moved up to the
top of Annex G as one main point of IEEE 654 arithmetic and the LIA
standards is consistency, and specifying it this way definitely
encourages (and even requires) inconsistency. So the first part of G.4.1
paragraph 4 should be moved to G.1 and the following added:
A complex number with one component a NaN and the other a finite
number is a complex NaN.
I can't say that I like this, because a complex NaN can turn into a
complex infinity, which is the converse of the rule for real numbers. I
would prefer the NaN property to take priority over the infinity one.
G.3.2 Real and imaginary and G.3.3 Imaginary and complex are
unnecessarily repetitive and forbid any consistent handling of NaNs and
infinities. I suggest replacing them both by wording that
cross-references the main body of the standard, such as:
G.3.2 Imaginary, real and complex
When a value of imaginary type is converted to a real or complex
type, it is treated as if it were its corresponding real type, converted
to its corresponding complex type, multiplied by _Complex_I and converted
to the result type.
When a value of real or complex type is converted to an imaginary
type, it is treated as if it were multiplied by _Complex_I, and converted
to the result type as if that were its corresponding real type.
As mentioned under 6.2.1.6, the current wording is seriously incompatible
with the spirit of IEEE 754 and LIA-1, in that information can be lost
without flagging the fact in any way. With IEEE 754 arithmetic, the
obvious way to indicate the loss of information is the inexact exception,
but most people's experience is that is raised too often to be useful.
However, it should be explicitly allowed. I suggest adding the following
to G.3:
1 When a complex, real or imaginary finite or infinite number is
converted to one of the other two forms and the converted number does not
compare equal (as if using the =3D=3D operator) to the original value, it i=
s
implementation-defined whether the inexact exception will be raised.
2 When a complex, real or imaginary NaN is converted to one of the
other two forms and the converted number is not a NaN, it is
implementation-defined whether one of the invalid or inexact exception
will be raised and, if so, which.
[ Note that conversion WITHOUT raising exceptions is provided by the
creal and cimag functions, so this is not a restriction. ]
Public Comment Number PC-UK0164
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: G.4.1
Title: Complex multiplicative operators
Detailed description:
Paragraph 5 sends shudders up my spine but, unfortunately, it is obvious
why it has to allow spurious exceptions. However, I am 99% certain that
efficient implementations are possible while raising spurious invalid,
overflow and underflow exceptions only in borderline =3Dcases. But please
note that I am only 99% certain! I suggest adding the following:
Recommended practice
A good implementation will not produce spurious invalid exceptions,
except possibly when at least one of the component values is an infinity
or a NaN. It will not produce spurious overflow or divide-by-zero
exceptions, except possibly when abs(x)*abs(x) for at least one of its
operands would overflow or be infinite or, for the second operand of the /
operator only, 0.5*abs(x)*abs(x) would underflow.
And, yes, I know that the example code fails to do this. However, in the
light of my comments on 7.14.2.2 The srand function, it is highly
desirable to have some wording that discourages implementors from taking
examples as normative code.
Public Comment Number PC-UK0165
Comment 1.=20
Category: Editorial change/non-normative contribution
Committee Draft subsection: H.3.1, H.3.1.2
Title: Incorrect claims of LIA-1 conformance
Detailed description:
LIA-1 6.1.1 point (c) requires the ability to permit the programmer to
specify code to compensate for exceptions if this form of exception
handling is used. C does not permit such code, but H.3.1 paragraph 4
claims that it does. In particular, there is no way to return a
corrected value after a numeric (SIGFPE) signal. This statement should be
corrected.
H.3.1.2 paragraph 4 claims that the C standard allows trap-and-terminate
as well as trap-and-resume. Both of these are undefined behaviour
(7.11.1.1 The signal function, paragraphs 3 and 5). While undefined
behaviour is not incompatible with LIA-1 (obviously), it is seriously
misleading to use it to claim that the C standard supports LIA-1 (see H.1
Introduction). This statement should be corrected.
Public Comment Number PC-UK0166
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.1.3
Title: Indication of failure
Detailed description:
The C standard does not make any requirement on an implementation to
distinguish success from failure during compilation, which causes a lot of
trouble with Unix 'make' and similar utilities. It would be possible to
require it to indicate failure in the cases when that is possible and it
produces at least one required diagnostic. But is this a good idea? If
it can be done without causing major trouble, then I think that it should
be done.
I have not included any text, as I am not convinced whether this is
feasible (practically and politically.)
Public Comment Number PC-UK0167
Comment 1.=20
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.5.5.2
Title: require side effects in VLA declarations to work normally
Detailed description:
6.5.5.2 paragraph 3 states in part:
It is unspecified whether side effects are produced when the size
expression is evaluated.
This rule will be extremely confusing to the normal programmer. It places
a unreasonable burden, particularly if the size is determined via a
function call. See the WG14 archives for a fuller discussion of the topic.
Replace this sentence with:
The size expression is evaluated in the normal way. For the purposes
of determining the order of evaluation of subexpressions, all expressions
in a declarator are evaluated simultaneously, as if they were combined by
addition operators [*].
[*] Thus /int v [n++][n];/ causes undefined behavior because the
expression /(n++)+(n)/ does. But /int v [n++] =3D { n++ };/ does not,
because there is a sequence point between the expressions in the =20
declarator and those in the initializer.
Public Comment Number PC-UK0168
Comment 1.=20
Category: Inconsistency
Committee Draft subsection: 6.5.7
Title: Clarify when VLA sizes are determined
NOTICE - this is a replacement for PC-UK0043, which is withdrawn.
Detailed description:
6.5.7p3 reads in part:
Any array size expression associated with variable length array
declarators shall be evaluated with the typedef name at the beginning of
its scope upon each normal entry to the block.
This wording appears to say that VLA typedefs are evaluated when the
block containing them is entered, even though this is not the case for any
other kind of declaration (including VLAs
themselves). For example:=20
{
int n;
n =3D 5;
int v1 [n];
n +=3D 2;
typedef int vec [n];
n +=3D 2;
vec v2;
/* ... */
}
The above wording would imply that vec, and so v2, contains either 5 or
an undefined number of elements, rather than 7 that the average programmer
would expect.
It is also worthwhile clarifying the effects of a jump to a point between
the declaration and use of vec.
Change the wording to:
Any array size expression associated with variable length array
declarators shall be evaluated with the typedef name at the beginning of
its scope, and the resulting size shall be used whenever the
typedef name is subsequently used. If the scope of the typedef name is
entered by a jump rather than the normal sequence of execution, the
associated size is unspecified. If a typedef name is used in any
way while the associated size is unspecified, the behavior is undefined.
Public Comment Number PC-UK0169
Comment 1.=20
Category: Feature that should be included
Committee Draft subsection: 7.1.6
Title: relax restrictions on the offsetof macro
Detailed description:
The offsetof macro currently requires its first argument to be a
structure type, and is unclear what the second argument is. There is no
particular reason to forbid unions for the first argument, nor to forbid
complex constructs for the second argument, provided only that the
address constant requirement continues to hold.
In 7.1.6 paragraph 3, change "structure" to "structure or union" in two
places, and change:
The /member-designator/ shall be such that given
to:
The /member-designator/ may be any construct, provided that given
and add a footnote to the end of the paragraph:
[*] Thus the member-designator may be a construct like /m [2]/ or
/a.b.c/. The offset of any member of a union is 0.
Public Comment Number PC-UK0170
Comment 1.=20
Category: Request for information/clarification
Committee Draft subsection: 5.1.2.3
Title: Ordering of sequence points
Detailed description:
Paragraphs 2, 4 and 6 refer to the previous and next (or subsequent)
sequence points, but a expression parse tree does not have a canonical
ordering. Statements do, but they are irrelevant in this context.=20
This has caused considerable confusion with C89 in a fair number of
obscure but realistic constructions, as well in perverse ones like the
following:
(a,++b,a)+(a,++b,a)
I suggest adding a paragraph saying something like:
The ordering of sequence points within an expression is only
partially specified by the syntax rules and operator precedences, and an
implementation may reorder expressions in any way that is compatible with
those. A strictly conforming program shall not rely on any ordering of
sequence points that is not required by the syntax rules and operator
precedences.
I believe that this is normative in the sense that it makes it clear that
relying on any parse ordering is not strictly conforming, but that is
probably what was always meant.
Public Comment Number PC-UK0171
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.5.2
Title: Ambiguities and traps in VLAs
Detailed description:
Paragraph 3 says that it is unspecified whether side-effects in the sizes
of VLA declarators occur. I am at a loss to understand why this exclusion
is necessary or desirable, and its current wording is nothing but a trap
for the programmer. In particular, it conflicts very badly with the IEEE
and LIA arithmetic standards in that it explicitly permits exceptions to
occur and not be flagged.
Furthermore, there is no requirement that side-effects be handled
consistently, even for textually identical declarators within the same
function. Programmers will not expect such bizarre behaviour.=20
But perhaps the worst aspect is that it is unclear whether this lack of
specification is permitted to change the actual size, as in declarers
like:
int m =3D 10, n =3D 3;
typedef double x[(m +=3D 10, ++n, m+n)];
As the wording stands, it is unspecified whether this allocates an array
of length 13, 14, 23 or 24. I am sure that this was not meant, but it is
what the wording says. Worse still, consider a machine with 32-bit
integers and 16-bit operations - is it allowed to update only half of an
integer?
This situation is a recipe for chaos, and needs resolution. I suggest
one of the following solutions:
1) To define that side-effects occur as in ordinary expressions.
Algol 68 and other languages have shown that this is technically simple,
though existing compilers might need some reorganisation. There should be
no need for incompatible changes to compiled code. After all, the
compiler has to permit a function call, which can then do anything!=20
2) To make it a constraint error to use a VLA size expression that
has a side-effect or calls function. This would permit almost all
'reasonable' uses, diagnose those that were invalid and give
the implementor a very easy time. I doubt that most programmers would
ever notice the restriction.
Public Comment Number PC-UK0172
Comment 1.=20
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.7
Title: typedef and VLAs
Detailed description:
Paragraph 3 says that size expressions in VLAs are evaluated on entry to
the block, but this is unimplementable without further restrictions. For
example, consider the following:
int n =3D 3;
{ ...
int n =3D 5;
double a[n];
...
}
I am completely lost to know whether the declaration of 'a' gives a size
of 3 or 5 or is invalid. I sincerely hope that this sentence can simply
be dropped, and the size expressions in VLAs in typedefs evaluated where
every programmer will expect them to be - at the place the typedef
occurs. If not, considerable work is needed to say whether code like the
above is allowed and, if so, what it does.
Public Comment Number PC-UK0173
Comment 1
Category: Feature that should be included
Committee Draft subsection: 7.14.3
Title: The alloca 'function'
Detailed description:
The alloca 'function' is fairly common, but was quite rightly left out of
C89 on the grounds of implementation difficulty. However, the
introduction of VLAs provides precisely the right mechanism
to implement alloca, and this would help with porting some programs that
rely on it. There are a few that need it so badly that they cannot be
converted to use malloc.
Furthermore, many users would like a way of allocating space on the stack
and being able to trap failure in a reliable and moderately portable
fashion. One of the main arguments against VLAs is that they will reduce
program robustness - I don't agree, but the argument is being made. For
obvious reasons, alloca cannot be required to use the same space pool as
VLAs, but it is expected that most implementations will.
The specification here is intended to encourage implementors to return
NULL from alloca if space is not available, without making it impossible
to implement if detecting that state is infeasible. Note that it is
effectively always possible to raise a signal by probing the space after
allocation and before return, except on systems where the 'stack'
overflows into another data area and there is no global stack limit to
check against. However, I have not seen a system that broken in many
decades. Even on such a system, the following specification is
implementable by always returning NULL.
7.14.3.5 The alloca macro
Synopsis
[#1]
#include <stdlib.h>
void *alloca(size_t size);
Description
[#2] The alloca macro allocates space for an object with automatic
storage duration [6.1.2.4] whose size is specified by size and whose value
is indeterminate and returns the address of that object.
[#3] It is unspecified whether alloca is a macro or an identifier
declared with external linkage. If a macro definition is suppressed in
order to access an actual function, or a program defines an external
identifier with the name alloca, the behavior is undefined.
Returns
[#4] The alloca macro returns a pointer to the allocated space if
successful. An attempt to obtain more space than is available will either
return a null pointer or raise one of an implementation-defined set of
signals.
Recommended Practice
An implementation should attempt to return a NULL pointer as a
failure indication if possible. If it is impossible even to raise defined
signals reliably, the alloca macro should always return a null
pointer.
___________end of UK comments; begining of Switzerland comments __
Date: 24 February 1998
Author: Peter Scheibli
Postal Address: Swiss Association for Standardization, SNV
CH-8008 Zuerich,
Switzerland
E-mail Address: peter.scheibli@snv.ch
Comments on ISO/IEC CD 9899 (SC22N2620)
Number of individual comments: 10
COMMENT #1
-----------------------------------------------------
Category: Normative change to existing feature retaining the original
intent
CD Subsection: 6.5.2.1
TITLE: Structs with a flexible array member are not well defined.
Description:
Structs with a flexible array member (the so-called "struct hack") have a
number of problems. This is the first time that zero-sized objects are
introduced in C, which has a surprising number of consequences not
accounted for by the CD. (I communicated some of these problems to Clive
D.W. Feather <clive@demon.net>, who submitted similar changes to BSI in
the UK. Since I do not know the outcome of this, I'll restate them here.)
6.5.2.1, =A72:
Insert a new paragraph between =A72 and =A73 to define the constraints on
structs with a flexible array member:
"A structure with a flexible array member shall not be the type of a
member of a struct or of an element of an array. The same applies to a
union that contains (possibly recursively) a structure with a
flexible array member. If there is a flexible array member in a
structure, it must be the last member, and it must not be the only
member."
6.5.2.1, =A715
Needs rewording to avoid troubles with zero-sized objects, especially
the pointer-past-last-array-element rule.
"As a special case, the last element of a structure may have an
incomplete array type. This is called a flexible array member, and the
size of the structure shall be equal to the offset of the last element of
an otherwise identical structure that replaces the flexible array member
with an array of one element. When an lvalue whose type is a structure
with a flexible array member is used to access an object, it behaves as if
that member were replaced by the longest array with the same element type
that would not make the structure larger than the object being accessed.
If this array would have no elements, the only legal operation is taking
its address or its offset within the structure. Any attempt to access an
element of such an empty flexible array member or to set a pointer past
its last element results in undefined behavior."
6.5.2.1, =A717
It's not clear what "s1 and s2 behave as if" means in this context.
E.g., sizeof (*s1) will most probably *not* behave "as if". Hence my
reformulation:
Replace
"and assuming that the calls to malloc succeed, s1 and s2 behave as
if they had been declared as:"
by
"and assuming that the calls to malloc succeed, the objects pointed
to by s1 and s2 behave as if the two pointers had been declared as:"
6.5.2.1, =A718
Same correction. Replace
"they then behave as if they had been declared as:"
by
"the objects pointed to by s1 and s2 can then be accessed as if the
pointers had been declared as:"
COMMENT #2
-----------------------------------------------------
Category: Normative change to existing feature retaining the original
intent (Request for clarification)
CD Subsection: 6.3.16
TITLE: Assignment of structs with a flexible array member considered harmfu=
l.
Description
The current formulation does all w assignments between structures with a
flexible array member, but I cannot find anything in the CD that would
make the following illegal:
struct X {int n; int a[];};sent
void foo (struct X arg, int bar);
struct X a, *b, *c;
b =3D malloc (sizeof (struct X) + 6 * sizeof (int));
c =3D malloc (sizeof (struct X) + 18 * sizeof (int));
// Assume that both calls to malloc succeeded..., and
// assume sizeof (int) <=3D 6.
*b =3D *c; // Crash?
a =3D *b; // Crash?
foo (a, 42); // Crash?
foo (*c, 42); // Crash?
Even if the committee arrive at defining some semantics for such cases, I
doubt it would be practicable, for an implementation would be forced to
carry around the size of a malloc'ed block with each pointer or with the
block. (That might actually be a good idea -- it might give us array
bounds checking :-) I don't think it's the committee's intent. Note that
assignments could be simply forbidden by defining a struct with a flexible
array member as being an incomplete type, but I fear that this would again
need corrections to handle (correct) cases like
b->n =3D 42; // Since when can we access members of an
// incomplete type?
b->a[1] =3D 42; // Ditto.
sizeof (struct X) // sizeof of an incomplete type?
=20
Defining assignment of structures with a flexible array member as being
equivalent tp a memcpy, i.e.
a =3D *b;
as the same as
memcpy (&a, b, sizeof (struct X));
doesn't make sense either, as it would introduce a very special case in C
where an assignment doesn't copy the whole object but only a part of it.
I therefore propose to forbid all assignments between structures with a fle=
xible array member. (Since
arguments are passed "as if by assignment", parameter passing would also
be covered.)
6.3.16, =A72
Replace
"An assignment operator shall have a modifiable lvalue as its left
operand."
by
"The left operand of an assignment operator shall be a modifiable
lvalue whose type is neither a structure with a flexible array member nor
a union containing (possibly recursively) a member whose type is such a
structure."
COMMENT #3
-----------------------------------------------------
Category: Normative change to existing feature retaining the original
intent (Request for clarification)
CD Subsection: 6.5.8
TITLE: Initialisations of structures with a flexible array member
Description
Subsection 6.5.8, "Initialization", does not account for structures with
a flexible array member. What is supposed to happen in the following case:
struct X {int n; int a[]};
struct X a =3D { 7, {1, 2, 3, 4, 5, 6, 7} }; // OK
struct X b =3D { 42 }; // ??
void foo (struct X *p)
{
struct X copy =3D *p; // ??
// ...
}
The first case already is covered by the rules, but I think the second
needs clarification:
6.5.8, =A721
Insert a new paragraph between =A721 and =A722:
"If the initializer for a structure with a flexible array member does
not specify any element for the flexible array member, that member has
size zero, and the restrictions of 6.5.2.1, =A715 apply."
The third one also is critical, as it is *not* covered by the proposed
rule that assignments are not allowed for structs with a flexible array
member. (Initialization is not defined in terms of assignment!)
In fact, I think that the third case would be useful, but once again,
allowing it would force implementations to carry around the size of a
malloc'ed block with the block itself. To forbid the third case, 6.5.8,
=A715 must be changed:
6.5.8, =A715
New wording:
"The initializer for a structure that does not contain a flexible array
member and that has automatic storage duration or for a union that does
not contain (possibly resursively) a structure with a flexible array
member and that has automatic storage duration may be a single expression t=
hat has compatible
structure or union type. In this case, the initial value of the object is
that of the expression. All other initializers shall have the form of an
initializer list as described below."
COMMENT #4
-----------------------------------------------------
Category: Editorial change
CD Subsection: various
TITLE: Typos
Description:
I have only listed those typos and layout errors I wasn't sure whether
they have not already been taken care of (I once published a list of such
errors in comp.std.c, and got an answer from Larry Jones
<larry.jones@sdrc.com> saying he'd noted them).
6.1.2, =A72: The second but last sentence should refer to annex I instead
of annex H.
6.3.2.2, =A76: Should be rephrased. If read in isolation, one comes to the
conclusion that any function declaration with a variable argument list
(the ellipsis notation) results in undefined behavior, which is
certainly not the intent.
6.3.2.2(6) only makes sense in connection with 6.3.2.2(5),
so the visual clues to emphasize this should be improved, e.g, by
inserting the text of 6.3.2.2(6) in 6.3.2.2(5) after the second sentence.
6.3.6, =A712: Correct "know" to "known" in the second line.
COMMENT #5
-----------------------------------------------------
Category: Editorial change
CD Subsection: 6.1.3.1, B.1.5
TITLE: Re-format the syntax
Description:
The syntax for hexadecimal floating point constants should be rewritten
as=20
hexadecimal-floating-constant:
hex-prefix hexadecimal-fractional-constant
binary-exponent-part floating-suffix(opt)
hex-prefix hexadecimal-digit-sequence
binary-exponent-part floating-suffix(opt)
hex-prefix:
0x
0X
In other words, I'd factor the "0x" part out of
hexadecimal-floating-constant to emphasize that there are basically only
two ways to write them, not four. (Note: the current syntax also is
correct, but in my opinion it's less clear.)
Anyway, why not give the syntax in EBNF instead of some ad-hoc
description? (I know, I know -- C89 introduced this ad-hoc notation and
people got used to it, so we're stuck with it...)
COMMENT #6
-----------------------------------------------------
Category: Feature to include
CD Subsection: 7.15.5.8
TITLE: Reentrant version of strtok.
Description:
It is common knowledge that strtok() is not reentrant, which causes
problems when it should be used to tokenize two strings at the same time
(e.g., in nested loops.) Also, using strtok() may break independence of
functionality if used in other functions -- if one uses strtok while
calling still other functions, one has to know whether these other
functions also use strtok() for some purpose.
These well-known problems could all be resolved if we had a re-entrant
version of strtok(), i.e. one that doesn't depend upon global intermediary
state. Document WG14 N687 did propose such a reentrant strtok(), called
strsep(). This proposal (see URL
<http://www.dkuug.dk/JTC1/SC22/WG14/www/docs n687.htm>) is reproduced
below:
>>>> Begin inclusion from N687:
1: Strtok cannot handle empty fields.
2: Strtok cannot handle more than a single string at a time.
=20
Proposal:
Provide strsep as a replacement.
char * strsep(char **stringp, char *delim);
The strsep() function locates, in the string referenced by *stringp,
the first occurrence of any character in the string delim (or the
terminating `\0' character) and replaces it with a `\0'. The
location of the next character after the delimiter character (or NULL, if
the end of the string was reached) is stored in *stringp. The original
value of *stringp is returned.
<<<< End inclusion from N687.
At the danger of re-iterating old stuff (according to Peter Seebach in
msg <5p5qfh$4sa$1@blackice.winternet.com> in comp.std.c, strsep() did not
get sufficient support at the London meeting), I strongly urge the
committee to reconsider its decision and to include strsep() as proposed
in the standard. It fixes the problems strtok() has in a clean way, poses
no backwards compatibility problems (its name is in a name space that was
already reserved in C89), and is a very useful addition to the standard
library.
Note: I do not propose to *replace* strtok() by strsep(), just to *add*
strsep(), thus existing C89 programs can continue to use the older
strtok().
COMMENT #7
-----------------------------------------------------
Category: Normative change to existing feature retaining the original
intent
CD Subsection: 5.2.4.1
TITLE: UCNs and translation limits
Description:
5.2.4.1, =A71 gives various minimum limits a conforming implementation must
support, amongst them:
- 63 significant initial characters in an internal identifier or macro
name
- 31 significant initial characters in an external identifier If the
identifier contains universal character names, it is unclear whether a UCN
counts as 1, 4, 6, 8, or even 10 characters when considering the
above limits. The wording in the CD must be corrected to clarify this.
COMMENT #8
-----------------------------------------------------
Category: Feature to remove
CD Subsection: 6.1.8
TITLE: UCNs in preprocessing numbers
Description:
The syntax in 6.1.8, =A71, reads:
pp-number:
digit
. digit
pp-number digit
pp-number nondigit
...
and 6.1.2, =A71, defines "nondigit" as
nondigit: one of
universal-character-name
_ a b c ...
This would allow UCNs to appear in the midst of a preprocessing number.
Is this intentional? I suspect not, and propose therefore that the syntax
be corrected to disallow UCNs in preprocessing numbers.
COMMENT #9
-----------------------------------------------------
Category: Normative change to intent of existing feature
CD Subsection: 6.1.1
TITLE: "complex" should always be a keyword
Description:
6.1.1, =A72 defines "complex" as a keyword only iff the header <complex.h>
is included. Such "conditional keywords" are a particularly ugly hack. I
don't quite see the rationale for this, either: backwards compatibility
with C89 already is compromised by the new keywords "restrict" and
"inline" and the requirement that there must be at least one type
specifier in a declaration (i.e, no default to int).
I therefore propose to make complex a first-class keyword that is always
reserved, just like the other keywords. 6.1.1, =A72 should be adapted
accordingly.
COMMENT #10
-----------------------------------------------------
Category: Request for clarification
CD Subsection: 6.1.1
TITLE: Imaginary types
Description:
The near-keyword "imaginary" is a slightly different case than "complex",
as its support is not mandatory. Still, I consider the provisions made for
imaginary equally ugly, and I'd be much happier if "imaginary" types could
be thrown out altogether.
What needs are imaginary types supposed to satisfy, anyway? Where's the
prior art? I can see only a few advantages: uses less space than
"complex", as no real part has to be stored, and notational
convenience. However, I suspect that imaginary types are not really
needed. One can use real floating types to represent them just as well,
and for mixed operations with other real floating types (used for
*real* values) or complex types, the appropriate conversions can be done
by the programmer.
If the intent was to provide some sort of type checking to guard against
inadvertent use of a real floating type that (for the application's
semantics) holds a coordinate on the imaginary axis as a *real"
value, I must say that C never was very strong at this, despite the
"typedef", and providing such strong type checking for this one special
case is no good. In this case, think about a way to offer strong type
checking for *all* types in general.
(If I'm not mistaken, BSI will recommed that "imaginary" be not a keyword
at all. As I don't know exactly what they're going to propose, [I don't
quite see how one can keep imaginary types without "imaginary" being a
keyword] I'm not offering my own proposition, but am just expressing my
opinion that imaginary types should be thrown out.)
The need for imaginary types must be critically re-evaluated.
________________________ end of SC22 N2690 ____________________________
________________________ beginning of title page ______________________
ISO/IEC JTC 1/SC22
Programming languages, their environments and system software interfaces
Secretariat: U.S.A. (ANSI)
ISO/IEC JTC 1/SC22
N2693
TITLE:
Contribution from Norway on Comments Accompanying the Summary of Voting on
CD Approval of CD 9899 - Information technology - Programming languages -
Programming Language C (Revision of ISO/IEC 9899:1990)
DATE ASSIGNED:
1998-04-17
SOURCE:
Secretariat, ISO/IEC JTC 1/SC22
BACKWARD POINTER:
N/A
DOCUMENT TYPE:
SC22 Member Body Contribution
PROJECT NUMBER:
JTC 1.22.20.01
STATUS:
WG14 is requested to consider this comment in its further deliberations on
the CD.
ACTION IDENTIFIER:
FYI to SC22 Member Bodies
ACT to WG14
DUE DATE:
N/A
DISTRIBUTION:
Text
CROSS REFERENCE:
SC22 N2620, N2690
DISTRIBUTION FORM:
Def
Address reply to:
ISO/IEC JTC 1/SC22 Secretariat
William C. Rinehuls
8457 Rushing Creek Court
Springfield, VA 22153 USA
Telephone: +1 (703) 912-9680
Fax: +1 (703) 912-2973
email: rinehuls@access.digex.net
_______________ end of title page; beginning of comment _______________
From: Magnus Y Alvestad <magnus@ii.uib.no>
Subject: Re: (SC22docs.478) SC22 N2690 - Summary of Voting on CD Approval of CD 9899 - C
This is a mistake:
| Country Positive format Negative format International format
|
| Italy L.1.234 -L.1.234 ITL 1.234
| Netherlands f 1.234,56 f -1.234,56 NLG 1.234,56
| Norway kr 1.234,56 kr 1.234,56- NOK 1.234,56
| Switzerland SFrs.1,234.56 SFrs.1,234.56C CHF 1,234.56
| Finland 1.234,56 mk -1.234,56 mk FIM 1.234,56
It should be:
Norway kr 1.234,56 kr -1.234,56 NOK 1.234,56
-Magnus
_________________ end of SC22 N2693 _____________________________________