JTC1/SC22/WG14
N841
Disposition of Comments Report for CD 9899, Ballot Document N2620
Document number: WG14 N841
J11/98-040
All responses are marked with a response code that corresponde with
the response codes attached, marked with "WG14:".
All responses marked E indicate Editorial and have been forwarded to
an editorial review group for their consideration.
CANADA:
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).
WG14: Response Code: NI
-----------------------------------------------------------------
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.
WG14: Response Code: Y
This proposal was accepted.
-----------------------------------------------------------------
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.
WG14: Response Code: IF
-----------------------------------------------------------------
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.
WG14: Response Code: N
A 16-bit implementation can support 64K-sized objects.
The type ptrdiff_t need not be able to store all pointer
differences, however, size_t can, as can the macros.
-----------------------------------------------------------------
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).
WG14: Response Code: M
The restriction is sufficient.
-----------------------------------------------------------------
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.
WG14: Response Code: CE
-----------------------------------------------------------------
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.
WG14: Response Code: N
-----------------------------------------------------------------
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).
WG14: Response Code: AN
-----------------------------------------------------------------
Danish Standards Association:
7.3.2 There should only be one expected result for the
toupper() and tolower() functions, respectively.
WG14: Response Code: M
The result is required to be consistent.
-----------------------------------------------------------------
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
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:
7.5 Localization <locale.h>
[#2] ...
char int_p_cs_precedes; /* CHAR_MAX */
char int_p_sep_by_space; /* CHAR_MAX */
char int_n_cs_precedes; /* CHAR_MAX */
char int_n_sep_by_space; /* CHAR_MAX */
char int_p_sign_posn; /* CHAR_MAX */
char int_n_sign_posn; /* CHAR_MAX */
7.5.2.1 The localeconv function
[#3] ...
char int_p_cs_precedes Set to 1 or 0 if the int_curr_symbol
respectively precedes or succeeds the value for a nonnegative formatted
monetary quantity.
char int_p_sep_by_space Set 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 Set to 1 or 0 if the int_curr_symbol respectively
precedes or succeeds the value for a negative formatted monetary
quantity.
char int_n_sep_by_space Set to 1 or 0 if the int_curr_symbol respectively
is or is not separated by a space from the value for a negative
formatted monetary quantity.
char int_p_sign_posn Set to a value indicating the positioning of the
positive_sign for a nonnegative formatted monetary quantity.
char int_n_sign_posn Set to a value indicating the positioning of the
negative_sign for a negative formatted monetary quantity.
In section 7.5.2.1 the examples need to be enhanced.
There cannot be a point after ITL.
Netherlands use a kind of small "f".
Norway 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.
WG14: Response Code: Y
The Committee adopted WG14 N821, this proposal incorporates
the desired features.
-----------------------------------------------------------------
7.5.2.1 The localeconv function
Examples
[#8] The following table illustrates the rules which may well be used
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
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
WG14: Response Code: Y
The Committee adopted WG14 N821, this proposal incorporates
the desired features.
-----------------------------------------------------------------
7.4.2.1 p_sep_by_space and n_sep_by_space
POSIX has added a third possibility for a formatted monetary quantity,
so now we have:
No space separates the currency_symbol from the value.
A space separates the symbol from the value.
*New* A space separates the symbol and the value, if these entities are
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.
WG14: Response Code: Y
The Committee adopted WG14 N821, this proposal incorporates
the desired features.
-----------------------------------------------------------------
7.5.2.1 The localeconv function
[#3] ...
char p_sep_by_space Set 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 Set 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 Set to 0 if no space separates the int_curr_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 int_n_sep_by_space Set to 0 if no space separates the int_curr_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.
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 "$".
p_sep_by_space
2 1 0
p_cs_precedes = 1 p_sign_posn = 0 ($ 1.25) ($ 1.25) ($1.25)
p_sign_posn = 1 + $1.25 +$ 1.25 +$1.25
p_sign_posn = 2 $1.25 + $ 1.25+ $1.25+
p_sign_posn = 3 + $1.25 +$ 1.25 +$1.25
p_sign_posn = 4 $ +1.25 $+ 1.25 $+1.25
p_cs_precedes = 0 p_sign_posn = 0 (1.25 $) (1.25 $) (1.25$)
p_sign_posn = 1 +1.25 $ +1.25 $ +1.25$
p_sign_posn = 2 1.25$ + 1.25 $+ 1.25$+
p_sign_posn = 3 1.25+ $ 1.25 +$ 1.25+$
p_sign_posn = 4 1.25$ + 1.25 $+ 1.25$+
------------------------------------------------------------------
WG14: Response Code: Y
The Committee adopted WG14 N821, this proposal incorporates
the desired features.
-----------------------------------------------------------------
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 (Monday=1).
%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=0).
%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.
--------------------------------------------------
WG14: Response Code: Y
The Committee adopted WG14 N821, this proposal incorporates
the desired features.
-----------------------------------------------------------------
Basic addressing of I/O hardware support should be included
in C9X, as I/O addressing support in C is of major importance for
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
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
can be fulfilled, without any inconvenience for those compilers for hosted
environments which do not want to support I/O addressing.
WG14: Response Code: N
There was insufficient interest by committee members to
make this change. This issue has been debated since 1995.
The Committee feels that there is insufficient technical
expertise within the working group, and there are efforts
outside this working group that are attempting to standardize
like features.
-----------------------------------------------------------------
FRANCE
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...)
WG14: Response Code: PR
-----------------------------------------------------------------
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).
WG14: Response Code: DA
The committee chose a different approach, see WG14 N837
UCN handling.
-----------------------------------------------------------------
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.
WG14: Response Code: AD
-----------------------------------------------------------------
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?
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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.
WG14: Response Code: Y
-----------------------------------------------------------------
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).
WG14: Response Code: Y
-----------------------------------------------------------------
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).
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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.
WG14: Response Code: Y
-----------------------------------------------------------------
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,
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.
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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.
WG14: Response Code: AL
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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".
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: AL
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: E
-----------------------------------------------------------------
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}
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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.
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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[] = mkstr(paste(\u, 0024));
as it will fool a number of implementations using preprocessors.
WG14: Response Code: DA
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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:
__STDC_ISO_10646__ A decimal constant of the form YyyyMmL
(for example 199712L), intended to indicate that the values
of the type wchar_t (as defined in the <stddef.h> header)
are the coded representations of the characters defined
by ISO/IEC 10646 (Universal Multiple-Octet Coded Character
Set, UCS), to the level specified by this standard with
all amendments applied up to the month "Mm" of the year
"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).
WG14: Response Code: Y
-----------------------------------------------------------------
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>.
WG14: Response Code: AD
-----------------------------------------------------------------
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.
WG14: Response Code: M
7.4 does not prohibit using implementation-specific modifiers.
-----------------------------------------------------------------
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
says:
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).
WG14: Response Code: EY
-----------------------------------------------------------------
JAPAN
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.
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
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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.
> Any source file multibyte character not in the basic
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> source character ...
makes clearer.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
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".
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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
"The type is incomplete".
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: AL
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EN
Maintaining compatibility between C and C++ is a goal
of both WG14 and WG21. We believe that this sort of
guidance is very useful.
-----------------------------------------------------------------
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?
Please make clear.
WG14: Response Code: EY
-----------------------------------------------------------------
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:
there are functions with the same name but with f
and l suffixes which are corresponding functions
with float and long double arguments and return
values.
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.
double nextafter(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).
float nextafterf(float, float);
long double nextafterl(long double, long double);
On the other hand, the "nextafterx" function is defined as
follows
The nextaferx function is equaivalent to the nextafrer
function except that the second parameter has type long
double.
In this case, the type of second parameter has only type
"long double".
According to this definition, type of second parameter
of the "nextafter" function may have only the type "double".
float nextafterf(float, double);
long double nextafterl(long double, double);
Which declarations of nextafter are correct? It is ambigious.
WG14: Response Code: AD
Explicit prototypes are now present in the Draft.
-----------------------------------------------------------------
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.
WG14: Response Code: ER
-----------------------------------------------------------------
2.16 Wrong notation in the example of fprintf/fscanf for
multibyte characters
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
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.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.)
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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.
WG14: Response Code: EY
-----------------------------------------------------------------
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)"
WG14: Response Code: SD
isblank and iswblank were not approved and should not have
appeared in the draft.
-----------------------------------------------------------------
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.
float nextafterxf(float, long float);
long double nextafterxl(long double, long long double);
Each second parameter shall have type "long double".
WG14: Response Code: EY
-----------------------------------------------------------------
2.22 Descriptions for some functions are not found
@ Annex "F.9.3 Exponential and logarithmic functions"
Page 499-501:
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.
WG14: Response Code: AD
These descriptions have been added to the
appropriate Annex.
-----------------------------------------------------------------
2.23 No more "common warning"
@ Annex "J Common Warnings"
Page 530, paragraph 2:
Following warning is no more "common warning".
- A function has return statements with and without
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:
A return statement with an expression shall not
appear in a function whose return type is void.
A return statement without an expression shall only
appear 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.
WG14: Response Code: EY
-----------------------------------------------------------------
2.24 Incomplete Annex K Portability issues
@ "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.
WG14: Response Code: M
The committee believes they have been included -- similar
topics are grouped together in annex K, so the wide
functions appear with the corresponding narrow functions
rather than having separate entries.
-----------------------------------------------------------------
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 -
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.
>
> Paragraph 1 of subclause 5.2.4.1 (page 19 in draft 9),
> paragraph 3 of subclause 6.1.2.5 (page 32 in draft 9),
> constraints of subclause 6.5.2 (page 83 in draft 9), and
> paragraph 2 of subclause 7.13 (page 258 in draft 9):
>
> 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
> optional specification or a part of the common extension of
> the standard C.
>
> A new type lldiv_t defined in subclause 7.13 should be
> reconsidered as well as type long long int.
>
> WG14: The Committee believes that the current WD is specifing current
> pracitice. The Committee also believes that the benifit to the user
> community out weights the cost of implementation for this feature.
>
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.)
WG14: Response Code: PR
-----------------------------------------------------------------
3.2 The function atoll() is redundant as the ISO C language
standard
> 1. Technical Comments
> 3) Function atoll() should be dropped.
>
> Subclause 7.13.1.4 (page 260 in draft 9):
>
> 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.
>
> 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:
- 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.
Please make the criteria of intorduction of new functions
clear.
WG14: Response Code: PR
-----------------------------------------------------------------
3.3 Example of ## operator
> 1. Technical Comments
> 5) Illegal example of ## operator
>
> Paragraph 4 (example) of subclause 6.8.3.3 (page 131 in
> draft 9):
>
> In the Example of the ## operator(paragraph 4 of
> subclause 6.8.3.3 (page 131)), that is,
> -----------------------------------------------------
> #define hash_hash # ## #
> #define mkstr(a) # a
> #define in_between(a) mkstr(a)
> #define join(c, d) in_between(c hash_hash d)
>
> char p[] = join(x, y); /* equivalent to */
> /* char p[] = "x ## y"; */
>
> The expansion produces, at various stages:
>
> join(x, y)
>
> in_between(x hash_hash y)
>
> in_between(x ## y) ---- line (A)
>
> mkstr(x ## y)
>
> "x ## y"
> -----------------------------------------------------
>
> an object-like macro "hash_hash" is replaced by "##" at
> line (A). Well then, what kind of preprocessing-token is
> the "##" at line (A)?
>
> 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:
> In other words, expanding hash_hash produces a new
> token, consisting of two adjacent sharp signs, but
> this new token is not the catenation operator.
>
> This description certainly says that ## is a token, but
> it is not the operator.
>
> Well, for the above description, should we read like
> the following sentence?
> ...this new token is the operator as
> preprocessing-token, but does not function as the
> catenation operator.
>
> 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:
> The operators # and ## shall occur in macro-defining
> preprocessing directives only.
>
> 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):
> If the result is not a valid preprocessing token,
> the behavior is undefined.
>
> 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.
>
> WG14: The current WD has new preprocessor token wording, that
> the Committee believes make the WD clearer in the area.
> The example is correct.
There are NO improvement about this problem in the current
CD (SC22 N2620.)
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.
WG14: Response Code: SD
-----------------------------------------------------------------
3.4 Old reference to ISO/IEC 646
> 2. Editorial Comments
> 1) The reference ISO/IEC 646:1983 must be ISO/IEC 646:1991.
>
> Paragraph 1 of clause 2 (page 2 in draft 9):
>
> The normative reference for ISO 7-bit codes character set is
> defined as ISO 646:1983. That is old. It must be the
> latest one ISO/IEC 646:1991.
>
> 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.
WG14: Response Code: EY
-----------------------------------------------------------------
3.5 Locale-specific behavior
> 2. Editorial Comments
> 2) Locale-specific behavior
>
> Paragraph 4 of Clause 4 (page 6 in draft 9):
>
> 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.
>
> WG14: The WD will be corrected.
There is no correction in the current CD (SC22 N2620).
Please correct it.
WG14: Response Code: EY
-----------------------------------------------------------------
3.6 Terminology of a null character
> 2. Editorial Comments
> 4) Terminology of a null character
>
> A many variety of the representation of "null character"
> is used in the draft 9.
> For example,
> - 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)
>
> So, they should be represented by using a same term.
>
> WG14: The Committee discussed this issue, and reached the consensus
> that a more detailed proposal would be needed to make such a
> 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)"
WG14: Response Code: AL
-----------------------------------------------------------------
3.7 Placemaker
> 2. Editorial Comments
> 5) Placemaker should be included in preprocessing token.
>
> Paragraph 1 (syntax) of Subclause 6.1 (page 26 in draft 9):
>
> Placemaker defined in 6.8.3.2 is not included in
> the syntax of preprocessing token. It should be included.
>
> WG14: The "placemarker" preprocessing tokens are conceptually
> introduced during translation phase 4 and are conceptually
> removed before the end of phase 4; their only function is
> to ensure that empty macro arguments are distinct entities
> during macro replacement, rather than vanishing too soon.
> Because "placemarker" preprocessing tokens cannot exist
> in the program source file, it would be inappropriate and
> confusing to show them in the formal grammar.
Japan requests to add the WG14's above explanation as a
footnote of placemarker.
WG14: Response Code: AL
-----------------------------------------------------------------
3.8 A double argument for the conversion specifier
> 2. Editorial Comments
> 14) A double argument for the conversion specifier
>
> Subclause 7.12.6.1 (page 232 - 233 in draft 9) and
> subclause 7.18.2.1 (page 308 - 309 in draft 9):
>
> In the description about the conversion specifier f, F, e,
> E and G of the function f[w]printf,
> "a double argument representing a floating-point number
> is..."
> should be changed to
> "a double argument representing a normalized
> floating-point number is..." ^^^^^^^^^^
> in order to clarify the range and the definition of the
> double argument.
>
> WG14: The Committee discussed this comment, and came to the
> 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
> 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>"),
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:
"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().
WG14: Response Code: AL
-----------------------------------------------------------------
United Kingdom
WG14: The following 6 statements are all resolved in the UK Public
Comments that follow.
Consideration should be given to the following:
(1) Change "complex" to be a true keyword.
(2) Remove the keyword "imaginary".
(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.
(4) Remove the "long long" type, and reinstate the concept that "long" is
the longest integer type.
(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.
(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.
Public Comment Number PC-UK0001
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
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0002
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0003
Comment 1.
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 ...
WG14: Response Code: NI
-----------------------------------------------------------------
Public Comment Number PC-UK0004
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0005
Comment 1.
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.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0006
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0007
Comment 1.
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.
WG14: Response Code: DA
The restrict qualifiers have been removed from functions
like fopen.
-----------------------------------------------------------------
Public Comment Number PC-UK0008
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0009
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0010
Comment 1.
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]
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0011
Comment 1.
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/.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0012
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0013
Comment 1.
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
element 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
of the last member of an otherwise identical structure that replaces the
flexible 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:
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0014
Comment 1.
Category: Inconsistency
Committee Draft subsection: 6.5.8
Title: problems with initializing unsigned char arrays.
Detailed description:
Consider the following declaration:
unsigned char s [] = "\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 [] = "\xFF";
is identical to:
unsigned char c [2] = { 0xFF, 0 };
and not to:
unsigned char c [2] = { (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/).
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0015
Comment 1.
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.
WG14: Response Code: N
-----------------------------------------------------------------
Public Comment Number PC-UK0016
Comment 1.
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.
* 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/.
WG14: Response Code: DA
The identifiers "_Complex" and "_Imaginary" are always
keywords now.
-----------------------------------------------------------------
Public Comment Number PC-UK0017
Comment 1.
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 == (equal to) and != (not equal to) operators are analogous to
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
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.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0018
Comment 1.
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.]]
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0019
Comment 1.
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 = "\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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0020
Comment 1.
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]]
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0021
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0022
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0023
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0024
Comment 1.
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0025
Comment 1.
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 = decimal
O/H = 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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0026
Comment 1.
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.
WG14: Response Code: EN
-----------------------------------------------------------------
Public Comment Number PC-UK0027
Comment 1.
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
universal-character-name).[122]
WG14: Response Code: E
-----------------------------------------------------------------
Public Comment Number PC-UK0028
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0029
Comment 1.
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)
WG14: Response Code: CE
Draft is clear enough as is.
-----------------------------------------------------------------
Public Comment Number PC-UK0030
Comment 1.
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.
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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0031
Comment 1.
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
/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.]
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0032
Comment 1.
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".
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0033
Comment 1.
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).
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0034
Comment 1.
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
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0035
Comment 1.
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".
WG14: Response Code: AN
Allowing ++ and -- to operate on complex values
is surprising in that similar operations on
imaginary values do not produce the same results.
-----------------------------------------------------------------
Public Comment Number PC-UK0036
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0037
Comment 1.
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".
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0038
Comment 1.
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
accordingly.
WG14: Response Code: N
The syntax is as intended; this is useful when using the ##
operator to create identifiers.
-----------------------------------------------------------------
Public Comment Number PC-UK0039
Comment 1.
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".
- 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.
WG14: Response Code: AN
Freestanding implementations do not have to provide
complex types and an 'i' suffix introduces complex
values into the language in another way.
-----------------------------------------------------------------
Public Comment Number PC-UK0040
Comment 1.
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
is 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.
WG14: Response Code: N
A diagnostic is not desired as this is a common extension.
-----------------------------------------------------------------
Public Comment Number PC-UK0041
Comment 1.
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 = 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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0042
Comment 1.
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/)
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0044
Comment 1.
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.
WG14: Response Code: E
-----------------------------------------------------------------
Public Comment Number PC-UK0046
Comment 1.
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]
- 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]"
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0047
Comment 1.
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0048
Comment 1.
? 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.
WG14: Response Code: SD
See WG14 N837 UCN Handling. UCN's are not longer
converted in phase I.
-----------------------------------------------------------------
Public Comment Number PC-UK0049
Comment 1.
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
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,
whether ...
WG14: Response Code: SD
Please see WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0050
Comment 1.
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.
WG14: Response Code: M
The implementation-defined behavior does not prohibit trap
representations.
-----------------------------------------------------------------
Public Comment Number PC-UK0051
Comment 1.
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).
WG14: Response Code: SD
-----------------------------------------------------------------
Public Comment Number PC-UK0052
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0053
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0054
Comment 1.
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.
WG14: Response Code: II
-----------------------------------------------------------------
Public Comment Number PC-UK0055
Comment 1.
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.
WG14: Response Code: AL
It is now possible to redefine the "I" macro.
-----------------------------------------------------------------
Public Comment Number PC-UK0056
Comment 1.
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.).
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0057
Comment 1.
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
current 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
with streams.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0058
Comment 1.
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.
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
number of open streams (FOPEN_MAX). The limit of /TMP_MAX/ could be
shared with calls to /tmpnam/.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0059
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0060
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0061
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0062
Comment 1.
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.
It is implementation-defined which changes of mode (if any) are permitted
and under what circumstances.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0063
Comment 1.
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
/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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0064
Comment 1.
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0065
Comment 1.
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.
WG14: Response Code: Q
DR63 has been answered, please see WG14 N829 or the updated
WG14 DR log.
-----------------------------------------------------------------
Public Comment Number PC-UK0066
Comment 1.
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.
WG14: Response Code: E
-----------------------------------------------------------------
Public Comment Number PC-UK0067
Comment 1.
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.
WG14: Response Code: E
-----------------------------------------------------------------
Public Comment Number PC-UK0068
Comment 1.
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 = numer / denom, .rem = numer % denom }; }
Alternatively, simply replace the entire description by the code in the
suggested footnote.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0069
Comment 1.
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.
WG14: Response Code: AN
The committee discussed this and found this
introduced technical problems.
----------------------------------------------------------------
Public Comment Number PC-UK0070
Comment 1.
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.
WG14: Response Code: AN
-----------------------------------------------------------------
Public Comment Number PC-UK0071
Comment 1.
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
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).
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0072
Comment 1.
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
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.
WG14: Response Code: AN
The committee considered the addition of _exit(), but
rejected it based on concerns of incompatible with the
POSIX specitication upon which it is based.
-----------------------------------------------------------------
Public Comment Number PC-UK0073
Comment 1.
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-0074
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
object, yield pointers to the remaining bytes of the object.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-0075
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
<[email protected]> 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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0076
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/
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
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
to the host environment is unspecified.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0077
Comment 1.
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 = 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 = 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 = 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.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0078
Comment 1.
Category: Normative change to existing feature retaining the original intent
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).
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0079
Comment 1.
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
the 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".
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0080
Comment 1.
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.
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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0081
Comment 1.
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 '$' <= 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.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0082
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0083
Comment 1.
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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0084
Comment 1.
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.
WG14: Response Code: SD
See WG14 N837 UCN handling.
-----------------------------------------------------------------
Public Comment Number PC-UK0085
Comment 1.
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.)
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0086
Comment 1.
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 == 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
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0087
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0088
Comment 1.
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
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0089
Comment 1.
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; ...
WG14: Response Code: M
There are intentionally no requirements for buffering, the
standard describes only the intended semantics.
-----------------------------------------------------------------
Public Comment Number PC-UK0090
Comment 1.
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.
[ 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. ]
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0091
Comment 1.
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.
WG14: Response Code: DI
-----------------------------------------------------------------
Public Comment Number PC-UK0092
Comment 1.
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:
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.
WG14: Response Code: M
Only the user-visible indicators must be cleared, there is
nothing to prevent an implementation from keeping an internal
indicator that causes the user-visible indicator to be
immediately reset on the next operation.
-----------------------------------------------------------------
Public Comment Number PC-UK0093
Comment 1.
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
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! ]
WG14: Response Code: LU
-----------------------------------------------------------------
Public Comment Number PC-UK0094
Comment 1.
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 ([email protected]) 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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0095
Comment 1.
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 function, 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.
WG14: Response Code: LU
-----------------------------------------------------------------
Public Comment Number PC-UK0096
Comment 1.
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-generated
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0097
Comment 1.
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 [email protected].
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
raised during the execution of a signal handler) are supported. This
support may be signal-dependent and there may be other
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0098
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0099
Comment 1.
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.
WG14: Response Code: Y
-----------------------------------------------------------------
Public Comment Number PC-UK0100
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0101
Comment 1.
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".
WG14: Response Code: AL
-----------------------------------------------------------------
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.
WG14: Response Code: BC
-----------------------------------------------------------------
Public Comment Number PC-UK0103
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0104
Comment 1.
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
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.)
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0105
Comment 1.
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.
WG14: Response Code: Q
On the contrary, paragraph 15 carefully avoids introducing
the concept of zero-size objects by specifying the behavior
in terms of nonzero-size objects.
-----------------------------------------------------------------
Public Comment Number PC-UK0106
Comment 1.
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.
WG14: Response Code: M
-----------------------------------------------------------------
Public Comment Number PC-UK0107
Comment 1.
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).
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0108
Comment 1.
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. ]
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0109
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0110
Comment 1.
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.
WG14: Response Code: E
-----------------------------------------------------------------
Public Comment Number PC-UK0111
Comment 1.
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] = &a;
double **q = &b; /* This looks very odd */
p = &b; /* And so does this */
q = &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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0112
Comment 1.
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
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. ]
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0113
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0114
Comment 1.
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
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.
WG14: Response Code: RS
-----------------------------------------------------------------
Public Comment Number PC-UK0115
Comment 1.
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
to avoid wcstokneeding 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.
WG14: Response Code: E
-----------------------------------------------------------------
Public Comment Number PC-UK0116
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0117
Comment 1.
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.
WG14: Response Code: PR
-----------------------------------------------------------------
Public Comment Number PC-UK0118
Comment 1.
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 = NULL;
void h (int n, int * const restrict p, const int * const q,
const int * const r) {
int i;
*s = 0;
for (i = 0; i < n; ++i) *s += (p[i] = q[i]+r[i]);
}
double a[5], b[5], c;
s = &c; fred(5,a,b,b);
s = &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 = 0; i < n; ++i) p[i] = 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
modified 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] = ((char *)a)[sizeof(double)+1];
a[0] = 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 = a;
((char *)b)[5] = 0;
*c = 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] <= (unsigned char *)Q and (unsigned char
*)&P[N] >= (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 = 0; i < n; ++i) p[i] = 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.
WG14: Response Code: TR
-----------------------------------------------------------------
Public Comment Number PC-UK0119
Comment 1.
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.
WG14: Response Code: Q
FLT_ROUNDS is not guaranteed to be an lvalue
because the Draft does not explicitly state that
it is an lvalue. For example, "errno" is explicitly
defined to be a modifiable lvalue. The Draft explicitly
states when something is an lvalue, therefore,
FLT_ROUNDS is not an lvalue.
-----------------------------------------------------------------
Public Comment Number PC-UK0120
Comment 1.
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.)
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.
WG14: Response Code: CE
These terms are clear enough as is.
-----------------------------------------------------------------
Public Comment Number PC-UK0121
Comment 1.
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0122
Comment 1.
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)!=0, 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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0123
Comment 1.
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.
WG14: Response Code: PR
Hexadecimal floating-point constants provide a different view of
floating-point values that is quite valuable.
-----------------------------------------------------------------
Public Comment Number PC-UK0124
Comment 1.
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.)
WG14: Response Code: Q
The floating-point model used in the Draft makes the phrase
"discarding fractional part" clear.
-----------------------------------------------------------------
Public Comment Number PC-UK0125
Comment 1.
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
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0126
Comment 1.
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.
WG14: Response Code: CE
Three bullets in the floating-point environment <fenv.h>
section describe the intended model of use for all functions
calls (not just the library). Documentation is only one way
of knowing a function doesn't use floating-point.
Raising a floating-point exception does not necessarily,
by default, cause a trap. Instead, it just sets the
exception flag and allows execution to continue.
-----------------------------------------------------------------
Public Comment Number PC-UK0127
Comment 1.
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".
WG14: Response Code: M
fexcepts_t is not an integer type, it is an opaque type; the
macros are used by the various library functions that process
values of that type.
-----------------------------------------------------------------
Public Comment Number PC-UK0128
Comment 1.
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 ...
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0129
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0130
Comment 1.
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.
WG14: Response Code: DA
The implementation is permitted to define additional
rounding direction macros.
-----------------------------------------------------------------
Public Comment Number PC-UK0131
Comment 1.
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.
WG14: Response Code: Q
The return values for these functions have been changed to make
them consistent with the rest of the library functions. A
return value of zero now means success.
-----------------------------------------------------------------
Public Comment Number PC-UK0132
Comment 1.
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".
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0133
Comment 1.
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
other implementation-defined circumstances.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0134
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0135
Comment 1.
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!
Fromboth 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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0136
Comment 1.
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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0137
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0138
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0139
Comment 1.
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".
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0140
Comment 1.
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..
WG14: Response Code: SD
Substantial changes have been made to the Draft in this area.
-----------------------------------------------------------------
Public Comment Number PC-UK0141
Comment 1.
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).
WG14: Response Code: CE
The <math.h> clause discusses treatment of error conditions that
apply to all math functions.
-----------------------------------------------------------------
Public Comment Number PC-UK0142
Comment 1.
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.
WG14: Response Code: Q
The term "roundoff error" is a well defined term and
"extraordinary" has just the English meaning.
-----------------------------------------------------------------
Public Comment Number PC-UK0143
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0144
Comment 1.
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
macro returns nonzero
for an implementation-defined set of values and zero otherwise.
WG14: Response Code: CE
This macro tests the sign bit.
-----------------------------------------------------------------
Public Comment Number PC-UK0145
Comment 1.
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.
WG14: Response Code: PA
There is too much parior art in this area.
-----------------------------------------------------------------
Public Comment Number PC-UK0146
Comment 1.
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.
WG14: Response Code: TE
The recommendation causes loss of important information
-----------------------------------------------------------------
Public Comment Number PC-UK0147
Comment 1.
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.
WG14: Response Code: TE
The Rationale will be enhanced in this area.
-----------------------------------------------------------------
Public Comment Number PC-UK0148
Comment 1.
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.
WG14: Response Code: M
The NaN macro does not take an argument.
-----------------------------------------------------------------
Public Comment Number PC-UK0149
Comment 1.
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 entirely.
If this is not done, it needs to be excluded from the list of
type-generic macros in 7.9.1.
WG14: Response Code: CE
The current wording is clear enough.
-----------------------------------------------------------------
Public Comment Number PC-UK0150
Comment 1.
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
Comment numeric-28
WG14: Response Code: PR
This is the intended definition of fmax and fmin.
-----------------------------------------------------------------
Public Comment Number PC-UK0151
Comment 1.
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.
WG14: Response Code: Q
"degrees vs. radians" is discussed because some felt
this was useful information. In 7.7.4, it is metioned
for each function individually.
-----------------------------------------------------------------
Public Comment Number PC-UK0152
Comment 1.
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
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0153
Comment 1.
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."
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0154
Comment 1.
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?
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0155
Comment 1.
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.
WG14: Response Code: PR
-----------------------------------------------------------------
Public Comment Number PC-UK0156
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0157
Comment 1.
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?
WG14: Response Code: Q
All floating-point constants are evaluated at translation time.
Therefore:
static double fred[(int)7.5];
is unambiguous. This is further clarified in the next clause on
initialization.
-----------------------------------------------------------------
Public Comment Number PC-UK0158
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0159
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0160
Comment 1.
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.
WG14: Response Code: EY
-----------------------------------------------------------------
Public Comment Number PC-UK0161
Comment 1.
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.
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-00162
Comment 1.
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. ]
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0163
Comment 1.
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 == operator) to the original value, it is
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. ]
WG14: Response Code: N
Certain of the comments summarized in (6) recommend changes
of a scope that would require substantial committee deliberation
of complete written proposals. Although the recommendations
might lead to useful enhancements or alternative approaches,
the committee believes the current specification meets the
floating-point objectives noted in the NCEG charter and
carried over into J11.
-----------------------------------------------------------------
Public Comment Number PC-UK0164
Comment 1.
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 cases. 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.
WG14: Response Code: AL
Paragraph 5 is as strong as intended. Example 1 will be
clarified to better explain the tradeoffs.
-----------------------------------------------------------------
Public Comment Number PC-UK0165
Comment 1.
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.
WG14: Response Code: NC
That Annex only claims to document which parts of LIA that
C9X can support. C9X does not claim to require support
for all of LIA.
-----------------------------------------------------------------
Public Comment Number PC-UK0166
Comment 1.
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.)
WG14: Response Code: BS
-----------------------------------------------------------------
Public Comment Number PC-UK0167
Comment 1.
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++] = { n++ };/ does not,
because there is a sequence point between the expressions in the
declarator and those in the initializer.
WG14: Response Code: AN
The committee has reaffirmed this decision many times.
-----------------------------------------------------------------
Public Comment Number PC-UK0168
Comment 1.
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:
{
int n;
n = 5;
int v1 [n];
n += 2;
typedef int vec [n];
n += 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.
WG14: Response Code: AL
-----------------------------------------------------------------
Public Comment Number PC-UK0169
Comment 1.
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.
WG14: Response Code: NC
-----------------------------------------------------------------
Public Comment Number PC-UK0170
Comment 1.
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.
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.
WG14: Response Code: CE
-----------------------------------------------------------------
Public Comment Number PC-UK0171
Comment 1.
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.
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 = 10, n = 3;
typedef double x[(m += 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!
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.
WG14: Response Code: N
The committee has reaffirmed this decision many times.
-----------------------------------------------------------------
Public Comment Number PC-UK0172
Comment 1.
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 = 3;
{ ...
int n = 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.
WG14: Response Code: SD
-----------------------------------------------------------------
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.
WG14: Response Code: N
-----------------------------------------------------------------
Swiss Association for Standardization, SNV
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 <[email protected]>, 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, :
Insert a new paragraph between and 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,
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,
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,
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:"
WG14: Response Code: SD
-----------------------------------------------------------------
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
harmful.
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 = malloc (sizeof (struct X) + 6 * sizeof (int));
c = malloc (sizeof (struct X) + 18 * sizeof (int));
// Assume that both calls to malloc succeeded..., and
// assume sizeof (int) <= 6.
*b = *c; // Crash?
a = *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 = 42; // Since when can we access members of an
// incomplete type?
b->a[1] = 42; // Ditto.
sizeof (struct X) // sizeof of an incomplete type?
Defining assignment of structures with a flexible array member as being
equivalent tp a memcpy, i.e.
a = *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
flexible array member. (Since arguments are passed "as if by assignment",
parameter passing would also be covered.)
6.3.16
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."
WG14: Response Code: SD
-----------------------------------------------------------------
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 = { 7, {1, 2, 3, 4, 5, 6, 7} }; // OK
struct X b = { 42 }; // ??
void foo (struct X *p)
{
struct X copy = *p; // ??
// ...
}
The first case already is covered by the rules, but I think the second
needs clarification:
6.5.8,
Insert a new paragraph between and :
"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, 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,
must be changed:
6.5.8,
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
that 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."
WG14: Response Code: M
A structure type with a flexible array member is an incomplete
type; it is not possible to declare objects with incomplete type.
-----------------------------------------------------------------
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
<[email protected]> saying he'd noted them).
6.1.2, : The second but last sentence should refer to annex I instead
of annex H.
6.3.2.2, : 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, : Correct "know" to "known" in the second line.
WG14: Response Code: EY
-----------------------------------------------------------------
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
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...)
WG14: Response Code: EY
-----------------------------------------------------------------
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.
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 <[email protected]> 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().
WG14: Response Code: AN
-----------------------------------------------------------------
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, 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.
WG14: Response Code: SD
-----------------------------------------------------------------
COMMENT #8
-----------------------------------------------------
Category: Feature to remove
CD Subsection: 6.1.8
TITLE: UCNs in preprocessing numbers
Description:
The syntax in 6.1.8, , reads:
pp-number:
digit
. digit
pp-number digit
pp-number nondigit
...
and 6.1.2, 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.
WG14: Response Code: N
The syntax is as intended; this is useful when using the ##
operator to create identifiers.
-----------------------------------------------------------------
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, 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, should be adapted
accordingly.
WG14: Response Code: DA
The identifiers "_Complex" and "_Imaginary" are always
keywords now.
-----------------------------------------------------------------
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.
WG14: Response Code: PR
Rationale for the imaginary type is in document WG14/N339.
-----------------------------------------------------------------
------------------------------------------------------------------------
NORWAY
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
WG14: Response Code: DA
After the correction, the entry is no different than the
previous entry, so it has been removed.
------------------------------------------------------------------------
US Public comments on CD1 recieved from NCITS.
US PUBLIC REVIEW COMMENT #1
------------------------------------------------------------------------
Comment 1.
Category: Request for clarification
Committee Draft subsection: 6.1.1, 7.8
Title: 'complex' not always a keyword
Detailed description:
Section 6.1.1 states that 'complex' and 'imaginary' are reserved
keywords only if the <complex.h> header has been included by the source
program. In addition, the use of them prior to such an inclusion is
deemed undefined.
Why are they not treated as reserved words all of the time?
One possible explanation is that this is an attempt to limit the number
of existing programs that will break with the addition of new keywords.
This, however, seems to be a moot point since the use of either keyword
(without the inclusion of <complex.h>) results in undefined behavior.
Also, this is a weak argument in light of the fact that other new
keywords have been introduced into the language (e.g., 'restrict' and
'inline') which could break existing programs.
Another possible explanation might be that this is to preserve
compatibility with C++, since C++ uses 'complex' as a template class
name in its standard library.
A clarification of this matter seems to be in order.
An alternative is to require that 'complex' and 'imaginary' are always
reserved words, regardless of the inclusion of <complex.h> or not.
WG14: Response Code: DA
The identifiers "_Complex" and "_Imaginary" are always
keywords now.
-----------------------------------------------------------------
Comment 2.
Category: Request for clarification
Committee Draft subsection: 5.1.1.2, 5.2.1, 6.1.2
Title: Source characters not allowed as UCNs
Detailed description:
Section 5.1.1.2 states that UCN codes representing characters in the
source character set are not allowed within the source text. For
example, the following fragment is illegal:
int func(int i)
{
return \u0030; // \u0030 is '0'
}
int bar(int \u006A) // \u006A is 'j'
{
return \u006A + 1;
}
But this fragment is legal:
int foo(int \u00E1) // \u00E1 is 'a'+accent
{
return \u00E1 * 2;
}
There is little difference in these fragments. What is the reason for
the limitation on valid UCN codes?
Conceivably, a Unicode text editor might store all the characters in
a file as UCN sequences for maximum portability. Allowing most
characters to be written as UCNs but requiring a few characters to be
written strictly as 7-bit ISO-646 characters seems like an artificial
restriction.
A C compiler implementation could choose to convert all source
characters into 16-bit (or even 32-bit) codes internally, preferring
to convert UCNs into single internal codes as they are read. Why
should it be prevented from accepting every alphanumeric ISO-10646
character, instead of every alphanumeric character /except/ 'a'-'z'
et al?
WG14: Response Code: Q
The current specification allows for efficient lexing.
-----------------------------------------------------------------
US PUBLIC REVIEW COMMENT #2
------------------------------------------------------------------------
Comment 1.
Category: Normative change
Committee Draft subsection: 4, 6.8.8, 7.1.3.
Title: Useless __STDC__ macro
Detailed description:
Section 6.8.8 states that the predefined '__STDC__' macro has the value
1, indicating a conforming implementation. Section 4 states fairly
clearly just exactly what a "conforming" and a "strictly conforming"
implementation are. Section 7.1.3 states exactly what a "reserved"
identifier is.
While appealing in theory, the '__STDC__' macro is useless in practice.
Programmers typically test for '__STDC__' in order to ascertain the
answers to the following questions:
1. Does the implementation support the standard keywords and syntax
(such as 'const', 'void *', and prototypes)?
2. Does the implementation supply the standard header files (such
as <stdio.h> and <stdarg.h>)?
3. Does the implementation supply the standard library functions
(such as 'printf' and 'setjmp')?
For example, the following fragment is typical for use with compilers
that support a "compile in non-ISO K&R mode" switch, in order to allow
for correct declarations in both ISO and K&R modes:
#ifdef __STDC__
#define P(d) d
#else
#define P(d) ()
#endif
extern int my_foo P((int arg));
extern void my_bar P((const char *n));
While conforming compilers are allowed to have extensions, some
compilers deviate from 7.1.3 by providing keywords that reside in the
unreserved namespace. For example, Microsoft Visual C provides the
'near' and 'far' keywords as extensions (for dealing with segmented
pointer types on Intel hardware); as such, it is not conforming and so
does not define '__STDC__' at all, even though it supports the full
ISO C syntax and library. Other vendors, such as Sun, define
'__STDC__' but define it to 0, presumably to indicate that they
support the syntax and library of ISO C but still have extensions.
Some vendors' compilers have a "ANSI/ISO compliance" switch that, when
enabled, causes '__STDC__' to be defined as 1, but to cause all
nonconforming constructs to be flagged as errors; this is fine in
theory, but in practice it cripples a program, usually by disabling
the declarations for system functions or by flagging such calls as
errors.
Unfortunately, 6.8.8 does not define what value '__STDC__' should have
in such near-conforming implementations.
Theoretically, the '__STDC_VERSION__' macro can be tested to determine
what language features are supported. But there is no guarantee that
this macro will be defined properly by vendors either. (Indeed, it
isn't on many implementations.)
Proposal:
In order to clarify the issue, in the hopes of providing programmers a
more useful macro, I propose that 6.8.8 be changed to the following:
__STDC__ The decimal constant 1, indicating a fully conforming
implementation, or the decimal constant 0, indicating
a conforming implementation with extensions [note].
note: Such extensions would potentially cause some otherwise
conforming programs to be nonconforming (such as the addition
of keywords that are not reserved in this standard [7.1.3]).
Implementations that are not conforming (with or without
extensions) or that are incapable of translating strictly
conforming programs shall not define this macro.
(The very last "shall not" phrase might be considered a bit weak,
because it attempts to define what nonconforming compilers cannot do.
Such compilers, by their very nature, are not likely to abide by
anything a standard has to say.)
WG14: Response Code: BS
While the committee sympathizes with your concern, unfortunately,
the standard cannot comment on near-conforming or extended
implementations.
------------------------------------------------------------------------
US PUBLIC REVIEW COMMENT #3
------------------------------------------------------------------------
Comment 1.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.2.2.1.
Title: Modifiable argv pointers
Detailed description:
Section 5.1.2.2.1 "Program startup" states that the 'argv' parameter to
main() and the strings pointed to by the argv array shall be modifiable
by the program. However, no mention is made of whether or not the
pointers themselves shall be modifiable.
It is my understanding that some systems allow the pointers to be
modified without ill effects to the program, while other systems do
not.
Proposal:
In order to clarify the issue, I propose that the following be appended
to the last paragraph of [5.1.2.2.1 #2]:
Whether or not the pointers of the argv array shall be modifiable by
the program is implementation-defined. If they are modifiable, they
shall retain their last-stored values between program startup and
program termination.
WG14: Response Code: NC
There was unsufficient interest by committee members to make
this change.
------------------------------------------------------------------------
US PUBLIC REVIEW COMMENT #4
------------------------------------------------------------------------
Comment 1.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 7.1.6.
Title: NULL macro type
Detailed description:
Section 7.1.6 [#3] states that the standard macro 'NULL' expands to an
"implementation-defined null pointer constant".
I feel that the standard ought to restrict the use of the 'NULL' macro
to pointer expressions only, i.e., make it illegal to use 'NULL' as an
integer expression. As defined currently, 'NULL' can be defined as
'0' or '0L' as well as '((void*)0)'. The former two are integer
constants, allowing for the possibility of 'NULL' being used as an
integer constant on some implementations. Disallowing 'NULL' as an
integer constant would make this dubious practice illegal.
Proposal:
I propose the following change to [7.1.6 #3]:
[#3] The macros are
NULL
which expands to an implementation-defined null pointer constant of
pointer type; and ...
(The rest of the sentence is unchanged.)
Discussion:
[1]
The use of 'NULL' as an integer constant is an inappropriate
programming practice. Some examples are:
int i = NULL; // Should be 0
char ch = NULL; // Should be '\0' or NUL
memset(p, NULL, sz); // Should be '\0' or 0
if (ch > NULL) ... // Should be '\0' or 0
The 'NULL' macro ought to represent a pointer value, not simply a zero
value.
[2]
Many implementations could define 'NULL' thus:
#define NULL ((void*)0)
which meets the requirements above. A few implementations use a
representation other than "all bits zero" to represent a null pointer,
so they could define 'NULL' as something like this:
#define NULL ((void*)0x80000000) // ala IBM CICS
The definition above does not restrict the type of 'NULL' to anything
other than a pointer type; it is not required to be 'void*' per se,
but could be whatever type the compiler vendor deems appropriate. For
example:
#define NULL __null // Vendor A
#define NULL ((__notype*)0) // Vendor B
In these cases, '__null' and '__notype' are implementation-specific
reserved words with special meanings. (It is assumed that in both
cases the type of 'NULL' is "implementation-specific pointer type".)
WG14: Response code: NC
There was insufficient interest by committee members to make
this change. This and related issues have been debated a number
of times and if one were starting from scratch, NULL (or some
spelling thereof) would be a keyword that could only be used in
pointer contexts. However, at this late stage, we think it
inappropriate to require that NULL expand to an expression of
some pointer type, there is simply too much code that expects
NULL to expand to some form of zero-valued integer expression.
------------------------------------------------------------------------
PUBLIC REVIEW COMMENT #5
------------------------------------------------------------------------
Comment 1.
Category: Request for clarification
Committee Draft subsection: 5.2.2, 7.3.1.4, 7.3.1.6, 7.3.1.8.
Title: isprint('\t')
Detailed description:
Section 5.2.2 defines the semantics of the standard nongraphic
characters ('\a' through '\v'). Sections 7.3.1.4, 7.3.1.6, and 7.3.1.8
define the iscntrl(), isgraph(), and isprint() library functions.
What is not clear is whether the "nongraphic" characters of 5.2.2 are
printable or not; in particular, is the result of isprint('\t') true or
false? 5.2.2 states that '\t' et al are "nongraphic", which would seem
to imply that isgraph('\t') is false, and by implication, isprint('\t')
is also false.
It is also unspecified whether or not the "nongraphic" characters are
"control characters", i.e., it does not seem clear that iscntrl('\t')
must be true.
Vendors are inconsistent about this. (Unix vendors, for instance,
usually define isprint('\t')==0, while Microsoft Visual C defines
isprint('\t')!=0.) Most seem to agree that the "nongraphic" = characters
of 5.2.2 are control characters (so that iscntrl('\t') is true). But
'\t' appears to be a special case; yes, it's a control character, but
is it also a printable character (just like ' ')?
This should be clarified in the standard. (I personally think that
isprint('\t') should be false; after all, if it's true, shouldn't
isprint('\f') and others also be true? But I think that would be a
mistake.)
Perhaps the use of the word "nongraphic character" (in 5.2.2) should be
replaced with something more exact, such as "control character". And
perhaps the definitions of the iscntrl(), isprint(), and isgraph()
functions could be clarified so that it is impossible for some
character code X to be both iscntrl(X)!=0 and isprint(X)!=0, i.e.,
the "control" and "printable" (or "graphic") characters are defined as
mutually exclusive sets.
(As I recall, Clive D. W. feather wrote something on this before, but
apparently it didn't make it into the draft.)
WG14: Response Code: IF
-----------------------------------------------------------------
PUBLIC REVIEW COMMENT #6
-----------------------------------------------------------------
Comment 1.
Category: Feature that should be included
Committee Draft subsection: 7.16.3.6
Title: Century handling in strftime()
Detailed description:
(century handling in strftime)
There is no century handling within strftime(). With the new century
at hand this needs addressing . ISO C should include the %C
conversion specification which has been in the X/Open Portability
Guide since XPG4 (1992).
After %c insert a new line
%C is replaced by the century number (the year divided by 100 and
truncated to an integer) as a decimal number [00-99]
WG14: Response Code: Y
Proposal accepted
------------------------------------------------------------------------
PUBLIC REVIEW COMMENT #7
-----------------------------------------------------------------
Comment 1.
Category: Request for information/clarification
Committee Draft subsection: Introduction
Title: "recommended practice" part of Standard?
Detailed description:
Are the "Recommended practice" subsections part of the Standard?
By analogy with examples and footnotes, I suspect that they're
not.
WG14: Response Code: Q
Unlike examples and footnotes (which are for information only),
recommended practice subsections are a normative part of the
standard. However, they contain no requirements, and so do not
affect the conformance status of an implementation.
-----------------------------------------------------------------
Comment 2.
Category: Inconsistency
Committee Draft subsection: 1 / 5.2.4.1
Title: size/complexity constraints?
Detailed description:
Section 1 para. 2 bullet 5 says that the size and complexity are
not constrained, but the translation limits in section 5.2.4.1
seem to provide exactly such constraints.
WG14: Response Code: Q
The translations limits indicate certain minimum requirements.
Implementors are encouraged to provide as few contraints as
possible with respect to maximum size and complexity
-----------------------------------------------------------------
Comment 3.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 3
Title: typo #1
Detailed description:
I think the word "by" is missing in front of the word "being".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 4.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 3.2
Title: "actual parameter" oxymoron
Detailed description:
I would *not* say that (actual) arguments are ever known as
"actual parameter"; the word "parameter" strongly suggests
"formal parameter". Moreover, the pair of words "actual
parameter" appears nowhere outside of section 3.2. Please omit.
WG14: Response Code: DA
The term is now clearly deprecated.
-----------------------------------------------------------------
Comment 5.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 3.16
Title: "formal argument" oxymoron
Detailed description:
Similarly, "formal argument" strikes me as poor usage, and
appears nowhere outside of section 3.16. Please omit.
WG14: Response Code: DA
The term is now clearly deprecated.
-----------------------------------------------------------------
Comment 6.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 3.18
Title: undefined behavior and diagnostics
Detailed description:
The wording at the end of para. 1 could be read o suggest that
termination upon undefined behavior *does* require a diagnostic.
I suggest changing the last "(with the issuance of a diagnostic
message)" to "(with or without the issuance of a diagnostic
message)".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 7.
Category: Request for information/clarification
Committee Draft subsection: 5.1.1.1
Title: "linked" undefined
Detailed description:
The term "linked" appears in the last line of para. 1 and in
several other places, with fairly significant implication, and
although you and I know what it means, it is nowhere defined.
WG14: Response Code: Q
Since the term `linked' is in widespread use in other
language standards and is well understood by practicing
programmers, the committee feels no compulsion to define
this term, especially since that term has no C-specific
conotations.
-----------------------------------------------------------------
Comment 8.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.1.1.2
Title: misplaced constraint on universal-character-name
Detailed description:
The second sentence of para. 2 seems as if it belongs in section
5.2.1 para. 5. (I'm not sure I agree with the constraint, but I
don't understand universal character names well enough to
comment.) At any rate, the "Forward references" for 5.1.1.2
should probably include 5.2.1.
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 9.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.1.2.2.1
Title: argc/argv modifiability, part 1
Detailed description:
I'd suggest removing the words "parameters argc and argv and the";
these parameters are obviously modifiable, as all parameters are.
(See also Comment 10.)
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 10.
Category: Request for information/clarification
Committee Draft subsection: 5.1.2.2.1
Title: argc/argv modifiability, part 2
Detailed description:
Is the array of pointers to char pointed to by argv modifiable?
WG14: Response Code: Q
This is currently implictly unspecified and the committee
has chosen to leave it that way.
-----------------------------------------------------------------
Comment 11.
Category: Normative change to existing feature retaining the original intent
Committee Draft subsection: 5.1.2.2.3
Title: exit / return from main equivalence
Detailed description:
I suggest moving the text of footnote 10 into the Standard.
This is a frequently debated issue, and I'm not aware that
footnote 10's statement is implied anywhere else in the Standard.
(Indeed, section 5.1.2.2.3 para. 1 seems to suggest otherwise.)
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 12.
Category: Request for information/clarification
Committee Draft subsection: 5.2.1
Title: other characters in comments, etc.
Detailed description:
What is the behavior when "any other characters" are encountered
*in* "a character constant, a string literal, a header name, a
comment, or a preprocessing token that is never converted to a
token"? Must they be allowed? I'd say it's implementation
defined, but I think the Standard should say so.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 13.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.2.1.1
Title: trigraph definition
Detailed description:
I'm not sure that word "corresponding" is obvious enough; I
might be more explicit and say "each of the three-character
sequences in the first column below is replaced with the
corresponding single character from the second column."
Also, this section may rate a forward reference to section 6.1.5;
when at first I didn't find the digraphs here, I thought they'd
been removed.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 14.
Category: Request for information/clarification
Committee Draft subsection: 5.2.1.2
Title: multibyte sequences/strings
Detailed description:
Although the term "multibyte character" is nicely defined,
the terms "multibyte sequence" and "multibyte string" are
introduced along the way (i.e. in later sections) as if we
already know what they are, and their precise definitions are
very hard to ferret out. It would be nice to collect them
here (or perhaps in section 3.14).
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 15.
Category: Request for information/clarification
Committee Draft subsection: 5.2.1.2
Title: source multibyte characters
Detailed description:
Paragraph 2 seems to be constraining source files, not the source
character set. (I'm not sure how to clarify this.)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 16.
Category: Normative change to intent of existing feature
Committee Draft subsection: 5.2.4.1
Title: object limit of 32767 should be retained
Detailed description:
In the previous revision of this Standard, the limit on the size
of an object was 32767. This allowed a 16-bit implementation to
use a 16-bit signed type for ptrdiff_t. If an implementation
must be able to handle at least one object of size 65536, and if
this object is an array of char, ptrdiff_t must be (at least) a
17-bit type, meaning a 32-bit type in practice, leading to an
unacceptable overhead on all *other* pointer differences. I feel
that the translation limit of 32767 bytes on the size of one
object should be retained.
(I comment separately on section 7.4.5, with respect to the same
issue.)
WG14: Response Code: M
The committee recognizes your concern, but chose to leave
the new minimum limits as they are. Note that for a very
large array, it is permitted that the difference between
pointers to elements in that array not be representable
by the type ptr_diff_t. This is disussed in the Rationale
Document.
-----------------------------------------------------------------
Comment 17.
Category: Other: comment
Committee Draft subsection: 5.2.4
Title: environmental limits scattered
Detailed description:
Several environmental limits appear elsewhere (specifically:
in sections 7.13.2 para. 7, 7.13.3 para. 14, 7.13.4.4 para. 6,
7.13.6.1 para. 14, 7.14.2.1 para. 5, 7.14.4.2 para. 3,
7.19.2.1 para. 14), and this fact may be worth noting somewhere
in section 5.2.4.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 18.
Category: Other: comment
Committee Draft subsection: 5.2.4.1
Title: some translation limits repeated
Detailed description:
A few of the translation limits in section 5.2.4.1 are repeated
elsewhere (specifically: in sections 6.5.5 para. 7, 6.1.2 para. 6,
6.6.4.2 para. 4), redundantly.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 19.
Category: Other: comment
Committee Draft subsection: 5.2.4.2
Title: numerical limits scattered
Detailed description:
Several numerical limits appear elsewhere (specifically: in
sections 7.4.2 and 7.4.5), and this fact may be worth noting in
section 5.2.4.2.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 20.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.2.4
Title: environmental limits scattered; some repeated
Detailed description:
In light of comments 17 to 19, para. 1 should probably
say "...summarizes most of the environmental limits...".
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 21.
Category: Request for information/clarification
Committee Draft subsection: 6.1.2.2
Title: multiply-defined symbols
Detailed description:
Should paragraph 7 say "within a translation unit and a scope"?
WG14: Response Code: Q
No
-----------------------------------------------------------------
Comment 22.
Category: Request for information/clarification
Committee Draft subsection: 6.1.2.4
Title: jumps into blocks containing "variably modified" objects
Detailed description:
In para. 3, in the sentence beginning "If the object is variably
modified", it is not clear to me what "variably modified" means
(or at least, it wasn't on first reading). Does this sentence
describe the antithesis of the previous sentence, namely for
objects that *do* have a variable length array type? If so,
please use identical terminology.
WG14: Response Code: Q
The term `variably modified' is defined in the draft
and the committee believs it is used consistently.
-----------------------------------------------------------------
Comment 23.
Category: Request for information/clarification
Committee Draft subsection: 6.1.2.5
Title: better description of "rank", part 1
Detailed description:
The word "rank" appears out of a clear sky in para. 7. It might
be nice to introduce or motivate this term with a sentence like
"For the purposes of describing the default conversions, each
{arithmetic/integer} type is assigned a rank." It might also be
nice, perhaps in a footnote, to provide a few words or an
example connecting this new concept of rank back to the more
familiar wording used in K&R or the previous Standard. (I see
that sec. 6.1.2.5 forward references sec. 6.2.1.1; perhaps that
suffices.)
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 24.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.1.2.5
Title: type and representation of `complex'
Detailed description:
With respect to para. 12, a complex type presumably also has the
same representation and alignment restrictions as the obvious
two-member struct, and this fact is probably worth explicitly
noting (i.e. specifying/requiring). (I'm not sure if homogeneous
structs are otherwise guaranteed to be equivalent to arrays, and
the reader may not be, either. But presumably if this guarantee
of equivalence to an array is considered useful, the analogous
guarantee for structs would be, too.)
WG14: Response Code: PC
Since two adjacent members of a structure can have padding
between them, no guarantee exists that a storage alignment
with complex types exist.
-----------------------------------------------------------------
Comment 25.
Category: Request for information/clarification
Committee Draft subsection: 6.1.2.5
Title: optionally named members?
Detailed description:
Does the word "optionally" in the second and third bullets of
para. 17 refer to unnamed bit-field members, or to something else?
WG14: Response Code: Q
Yes it does; the committee sees no other interpration.
-----------------------------------------------------------------
Comment 26.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.6
Title: multiply defined symbols
Detailed description:
Presumably, incompatible declarations of the same object or
function are undefined only if in different translation units.
Otherwise, they require a diagnostic. (If the wording here is
changed, change Annex K sec. K.2, also.)
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 27.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.8.1
Title: vague pronoun reference #1
Detailed description:
The word "that" in the first sentence of para. 2 has a vague
antecedent. I suggest replacing it with "a particular".
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 28.
Category: Request for information/clarification
Committee Draft subsection: 6.1.3.1
Title: floating-point constant overflow
Detailed description:
Perhaps I'm missing something, but it doesn't look as if para. 3
explains what happens if the the scaled value is *not* in the
range of representable values for its type. (The question is
particularly interesting since sec. 7.7 para. 4 makes explicit
reference to compile-time overflow of a floating-point constant.)
WG14: Response Code: Q
Constraint violation if value is not in range. The
constarint being violated is the one in 6.1.3.
-----------------------------------------------------------------
Comment 29.
Category: Feature (specification) that should be included
Committee Draft subsection: 6.1.3.4
Title: character constant limit
Detailed description:
I'm surprised there's no limit on the length of a character
constant, as there is for a string literal (see sec. 5.2.4.1
bullet 16, of course). I believe a reasonable limit on the
length of a character constant would be 4.
WG14: Response Code: N
The committee sees no reason to disallow very large character
sets. In any event, programs can already contain character
constants of the form '\x0000...0000n', where ... represents
an unlimited number of zeros and n represents some hexadecimal
number.
-----------------------------------------------------------------
Comment 30.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.5
Title: operator pairing wrt translation phase
Detailed description:
The first sentence of para. 2 should include the words "after
translation phase 4", as sec. 6.1.6 does.
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 31.
Category: Request for information/clarification
Committee Draft subsection: 6.1.5
Title: "designator"
Detailed description:
The word "designator" appears out of a clear sky in para. 3.
Grepping the rest of the document for this term reveals that
"function designator" is probably meant.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 32.
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.1.7
Title: undefined characters in header names
Detailed description:
I believe that the behavior if unusual characters appear in
h-char-sequences and q-char-sequences should be
implementation-defined, not undefined.
WG14: Response Code: N
The committee sees no compelling reason to require
implementors to document how they handle such characters.
-----------------------------------------------------------------
Comment 33.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.9
Title: continued // comments
Detailed description:
The fact that \ continues // comments is arguably wrong, and the
fact that the preexisting translation phases forced this
interpretation was (to my mind) the strongest arguments against
adopting them. Given the surprisingness of this result, I'd say
it rates a footnote ("Since backslash continuation occurs in
translation phase 2, and comments are parsed in translation phase
3, a \ effectively continues a // comment; that is, the \\ does
not "protect" the \ from interpretation") as well as appearing in
the examples.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 34.
Category: Request for information/clarification
Committee Draft subsection: 6.2.1.1
Title: better description of "rank", part 2
Detailed description:
As mentioned in comment 23, it might be nice to have a footnote
connecting this new concept of rank back to the more familiar
wording used in K&R or the previous Standard.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 35.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.2.2.3
Title: compatibility of converted function pointer types
Detailed description:
I believe that para. 8 should end with "...not compatible with
the type of the converted pointer, the behavior is undefined."
The function being called is always compatible with the called
function!
I think it would also be possible (and perhaps beneficial) to
delete the last sentence entirely; I believe that sec. 6.3.2.2
para. 8 says the same thing.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 36.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.2.2.3
Title: misc. wording #1
Detailed description:
In footnote 55, the word "yields" could be replaced (for more
clarity, I think) with "would yield".
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 37.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.2.2.3
Title: misc. wording #2
Detailed description:
In footnote 56, the words "correctly aligned" either need to be
in italics, or in quotes, or replaced with the words "of correct
alignment".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 38.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3
Title: undefined expression wording
Detailed description:
Although I understand it perfectly well now, for the longest
time the classic second sentence of para. 2 was almost
completely opaque to me. I might offer this replacement:
Furthermore, an object may not be accessed and modified
unless the access is { to determine / part of the
calculation of } the value to be stored.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 39.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3
Title: evaluation order and syntax
Detailed description:
The words "Except as indicated by the syntax" can be very
misleading. Many people believe that explicit parentheses,
or "operator precedence", *do* define aspects of evaluation
order which we know to be undefined. Changing the word
"subexpressions" later in the paragraph to "operands" might help.
(Unfortunately I can't immediately think of a more substantial
clear rewrite.)
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 40.
Category: Request for information/clarification
Committee Draft subsection: 6.3
Title: "object having no declared type"
Detailed description:
Is an "object having no declared type" one derived from malloc()?
(This paragraph is fascinating, by the way.)
WG14: Response Code: Q
Yes, from malloc.
-----------------------------------------------------------------
Comment 41.
Category: 6.3.1.1
Committee Draft subsection:
Title: "unadorned" name?
Detailed description:
The word "unadorned" appears almost nowhere else in this document.
Is its meaning sufficiently clear? (Just now, I'm not even sure
I understand its intent.)
WG14: Response Code: EY
The committee agrees that the term is unnecessarily misleading
and that an appropriate editorial change will be made. In
any event, the example makes it quite clear as to the format
of the resulting string given a function name.
-----------------------------------------------------------------
Comment 42.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.2.2
Title: semantics of function call semantics
Detailed description:
I commend the rewording over the 1989/1990 version, which was
nearly impossible to read. However, the breaking up into
paragraphs (which is otherwise a good idea), combined with the
paragraph numbers, leads to a new parsing challenge. Paragraph 6
is continuing the case that began in para. 5, but this may not
be obvious upon first reading. (When I first read para. 6 in
isolation, I could not understand it *at* *all*.) If at all
possible, I would remove the explicit paragraph number from
what is now para. 6.
Having learned that paragraphs 5 and 6 go together, we might then
assume that paragraphs 7 and 8 go together, but we'd be stymied
again! Paragraph 8 applies to both cases (the non-prototype case
of paras. 5/6 and the prototyped case of para. 7). It would be
nice to make this connection more clear as well.
Also, the clause "or if the prototype ends with an ellipsis" in
para. 6 seems redundant; it seems that para. 8 should cover (or
be made to cover) this case, as well, i.e. by the definition of
compatible type for function pointers (sections 6.1.2.6 and
6.5.5.3).
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 43.
Category: Other (comment)
Committee Draft subsection: 6.3.2.3
Title: -> definition
Detailed description:
Is there any reason not to define p->m as (*p).m? That seems
tidiest.
WG14: Response Code: Q
The committee acknowledges your suggestion is cleaner,
but it offers no new value, so the current words have
been retained.
-----------------------------------------------------------------
Comment 44.
Category: Request for information/clarification
Committee Draft subsection: 6.3.2.5
Title: confused about example 8
Detailed description:
I'm missing the point of example 8. The only difference I can
see between the two loops concerns the explicit braces, which I
guess is the point, but I'm still not seeing the point, or what
would be the same or different. The introductory paragraph
talks not about blocks but only about within/without a function
body, and the words "same sequence of values for the objects
associated with their respective compound literals" are just
meaningless.
Shouldn't the example be contrived to show some *difference*
between the two loops, i.e by having function f() inspect them
very carefully, or try to modify them?
Also, to avoid more confusion, the function in the following
example 9 should probably have a different name.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 45.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.3.3
Title: mildly confusing sequencing of - and ~
Detailed description:
The wording of paras. 3 and 4 is mildly awkward -- it sounds a
bit as if the operation is performed, then the integer promotion
is performed, then the result is obtained. (Inserting "first"
before "performed" in both places would help.)
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 46.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.3.4
Title: misc. wording #3
Detailed description:
In para. 4, the word "as" or a comma should be inserted between
"size_t" and "defined".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 47.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.6
Title: wording in example
Detailed description:
"know" should be "known". Also, it might read better in the
subjunctive: "If array... were declared..., and pointer... were
declared..., the results would be the same."
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 48.
Category:
Committee Draft subsection:
Title: Normative change to intent of existing feature
Detailed description:
Is it really the intent that bits not quietly fall off the left
edge when shifting signed values to the left, but rather that
the behavior be undefined? This seems a major change with
respect to the 1989/1990 version, although reviewing it, I see
that it didn't mention the signed case explicitly at all.
Unless there are viable architectures which are known to have
problems with this case, I'd very much like to see the signed
case well-defined as well. (Is the problem those pesky padding
bits?)
WG14: Response Code: Q
This issue was resolved in the committee's response
to Defect Report #81. The behavior is implementation-defined,
draft subsection is 6.3.7.
-----------------------------------------------------------------
Comment 49.
Category: Other (comment)
Committee Draft subsection: 6.3.8
Title: comparison of incomplete pointers
Detailed description:
Paragraph 2 bullet 3, para. 5 2nd sentence, and para. 5 last
sentence combine to say that if p and q have type void *, the
expression p >= q yields 1 if p == q and is undefined if p != q.
(I presume this is the intent.)
WG14: Response Code: M
You have misread the draft. p!=q yields false. An example
of undefined behavior in p>=q is when p and q are not
pointing into elements or members of the same array,
structure, or union.
-----------------------------------------------------------------
Comment 50.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.9
Title: pointer equality testing
Detailed description:
The wording in para. 4 seems cumbersome. Why not at least
shorten the third and fourth sentences to "Two pointers to
function types compare equal if and only if: they are both null
pointers or both point to the same function."
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 51.
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.3.9
Title: floating point equality
Detailed description:
Does there need to be an explicit caveat about the limitations of
testing for floating point equality? For example, I've heard it
alleged that the fragment
double a = b + c;
if(a != b + c) printf("impossible!")
might in fact print "impossible", if the register used to hold
the intermediate result of the second addition has more precision
than the object used to store c.
(Perhaps I'm wrong, or perhaps this issue is covered elsewhere.)
WG14: Response Code: N
See 6.2.1.7, paragraph 2.
-----------------------------------------------------------------
Comment 52.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.13, 6.3.14
Title: misleading wording concerning short-circuiting
Detailed description:
Since most operators do not guarantee left-to-right evaluation,
the words "Unlike the bitwise binary & operator" in sec. 6.3.13
para. 4 are potentially misleading. (By singling out & for this
comparison, the reader might assume that it's unique in this
regard.) No harm is done by removing the clause, and the
analogous one in sec. 6.3.14 para. 4.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 53.
Category: Request for information/clarification
Committee Draft subsection: 6.3.15
Title: conditional operator cases: exhaustive?
Detailed description:
Perhaps I'm nitpicking, but though I used to think that the cases
describing the second and third operands were nicely complete,
now I'm wondering if they cover the (admittedly degenerate) forms
e?NULL:NULL and e?(void *)0:0 .
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 54.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.16.1
Title: char/int truncation
Detailed description:
The word "may" in example 1 is potentially misleading. I
suggest something like "the int value... will be truncated
(assuming sizeof(int) > sizeof(char))..."
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 55.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.16.2
Title: semantics of compound assignment semantics
Detailed description:
The semantics description is one notch too terse. I'd expand it to
A compound assignment of the form E1 op= E2 is equivalent
to the simple assignment expression E1 = E1 op (E2), except
that the lvalue E1 is evaluated only once.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 56.
Category: Request for information/clarification
Committee Draft subsection: 6.4
Title: diagnostics on compile-time overflow
Detailed description:
The placement of para. 4 within the constraints section implies
that compile-time overflow is not undefined, but requires a
diagnostic. Is this in fact the case?
WG14: Response Code: Q
Yes, a diagnostic is required.
-----------------------------------------------------------------
Comment 57.
Category: Request for information/clarification
Committee Draft subsection: 6.5
Title: declaration constraints
Detailed description:
That word "excluding" in the parenthetical in para. 2 is a
stumper. What, exactly, does it mean? As worded, it seems like
it might be trying to say "above and beyond". It might be
clearer (if I even understand what it's trying to say) to reword
the parenthetical to "With the exception of function parameters
and members of structures or unions,", and place it at the front
of the sentence.
WG14: Response Code: Q
The committee believes the existing words to be clear.
-----------------------------------------------------------------
Comment 58.
Category: Request for information/clarification
Committee Draft subsection: 6.5
Title: declaration constraints
Detailed description:
To the bullet list in para. 5, is there anything to be added
about tags? (See e.g. sec. 6.5.2.3 paras. 1, 5.)
WG14: Response Code: Q
The committee believes the list to be complete.
-----------------------------------------------------------------
Comment 59.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5
Title: declaration semantics
Detailed description:
I'd find para. 6 easier to read if "have" were changed to "specify".
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 60.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.2
Title: complex declarations
Detailed description:
Shouldn't the keyword `complex' be able to appear alone,
defaulting to double complex? (Since keywords like `signed'
and `unsigned' can still appear alone, even though other
instances of default int are being weeded out, it seems harsh to
disallow plain complex.)
WG14: Response Code: PR
The keyword "complex" does not default to the type
"double complex" because Fortran default "COMPLEX" is
single precision and this could lead to confusion.
-----------------------------------------------------------------
Comment 61.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.2.3
Title: tag type completion
Detailed description:
Presumably the type is *incomplete* (para. 3) until the closing
brace, and complete thereafter.
WG14: Response Code: Y
The Committee has adopted this.
-----------------------------------------------------------------
Comment 62.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.3
Title: type qualifier examples
Detailed description:
Examples should not be in the running text of the Standard; the
sentence beginning "For example," in the middle of para. 7
should be moved or removed.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 63.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.3
Title: another qualified pointer example
Detailed description:
I propose adding a third example, concerning an obscure but not
uncommon situation:
The function call in the fragment
extern f(const char **q);
char *p;
f(&p);
violates a constraint (see section 6.3.16.1) and
requires a diagnostic. The call (or any assignment
of char ** to const char **) is unsafe, because if
function f were to perform the (valid) assignment
*q = &c;
where c was a const object, a later assignment by
the caller to *p (e.g. *p2 = 0) would in fact be
an attempted assignment to c.
This example is adapted from one in the book "C Programming
FAQs" which was supplied by Tanmoy Bhattacharya. The example
might go in section 6.3.16.1 instead, but it seems worth waiting
until qualified pointers have been fully introduced.
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 64.
Category: Request for information/clarification
Committee Draft subsection: 6.5.3.1
Title: clarification of `restrict'
Detailed description:
My understanding of `restrict' is far from complete, so these
questions may be misguided. The last half of para. 4 did not
seem (to me) to rule out the second and third undefineds in
example 4.
In para. 5, I'm not sure what "attention" means, and I'm not
sure *where* the "visible identifiers" are visible.
Where is "the exception" mentioned in example 4 stated?
What is the antecedent of the pronoun "this" in "this permits"?
*If* I'm understanding this section at all, I'd insert
"(necessarily single)" before "array object" in para. 4, and
change "an object" to "a (possibly hypothetical) object" in para. 5.
WG14: Response Code: Q
Part A: Since "p1" is associated with the outermost block
and is assigned a value based on a restrict-qualified
pointer from the inner block, the behavior is undefined.
Therefore the last half of paragraph 4 causes undefined
behavior in cited example.
Part B: The following change eliminates the word "attention" and
clarifies the intent.
Change the last two sentences of para. 5 in 6.7.3.1 from:
A reference to a value means either an access to or a
modification of the value. During an execution of B,
attention is confined to those references that are actually
evaluated.
to read:
An access to a value means either fetching it or modifying it;
expressions that are not evaluated do not access values.
and delete the associated footnote. Finally, the term "visible"
is a well defined term in the Draft (6.2.1).
Part C: The exception is "the execution of B2 shall end prior to
the assignment" which is further clarified in the second
half of EXAMPLE 4.
Part D: An object consists of a contiguous sequence of bytes, so
there is only 1 array object (6.2.6.1).
-----------------------------------------------------------------
Comment 65.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.3.1
Title: `restrict' examples
Detailed description:
It might be worth noting that many examples of `restrict' can be
found in section 7, e.g. in the declarations of functions such
as sprintf, strcat, and memcpy.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 66.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.4
Title: `inline' examples and rationale
Detailed description:
The clause "by using, for example, an alternative to the usual
function call mechanism known as `inline substitution'" should be
moved into footnote 101 to keep examples out of the Standard.
(Also, the modifier "known as" is ambiguously placed; apparently
it is meant to attach to "an alternative" rather than "the usual
function call mechanism".)
It's too bad that this Standard will apparently not come with
a Rationale document, as this section could really use one.
What optimizations, really, are hinted/encouraged by `inline'?
(Apparently not inlining across translation units.) Which
optimizations must a compiler still perform entirely on its own,
without hints? (Probably inlining across translation units.)
If there are some compilers that will never perform inlining
and some that are able to do it even without hints, what sorts
of compilers are there in the middle, that will need the hints?
[That's not a leading question; I honestly don't know the
populations of any of the three categories.]
I think I finally figured out that the sentence beginning "An
inline definition does not provide..." in para. 6 is suggesting
that it's okay to place inline function definition *in header
files*, so that they will be available across translation units.
An example demonstrating this would probably be helpful.
WG14: Response Code: E
-----------------------------------------------------------------
Comment 67.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.4
Title: naked subclause references
Detailed description:
I think the word "section" or "subclause" is missing before
"6.7" at the end of para. 8. (There are several examples of this
omission throughout the Draft; I'll point out a few others that
caught my eye. It's probably worth doing a global search for all
of them, if there's an easy way.)
WG14: Response Code: EN
ISO style is to omit ``subclause'' except for top-level
subclauses.
-----------------------------------------------------------------
Comment 68.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.5
Title: inconsistent metaname
Detailed description:
In paragraph 5, the two italicized words should presumably be the
same, both either "identifier" or "ident".
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 69.
Category: Other (comment)
Committee Draft subsection: 6.5.5.2
Title: restriction on variable-length types
Detailed description:
The two sentences in para. 2 seem to say the same thing.
If they truly do, one can be removed; if there is some
slight difference, it should probably be emphasized.
WG14: Response Code: Q
The first sentence permits local statics. The second
sentence probibits local static VLAs, but permits local
static pointers to VLAs. See Example 4, Array Declarators.
-----------------------------------------------------------------
Comment 70.
Category: Request for information/clarification
Committee Draft subsection: 6.5.5.3
Title: identifier lists in function declarators
Detailed description:
Paragraph 3 is tricky. After reading it several times, I
finally realized that it is talking about identifier lists,
*not* parameter type lists. So it is saying (of course) that
these can only occur in function definitions, not external
declarations; the declaration
extern int f(a, b);
is meaningless. But isn't it the case that some of the
identifier lists in function definitions need to be empty as
well? Consider
int (*f(a, b))(c, d) { ... }
The identifier list "c, d" is just as meaningless, and should
probably be disallowed. (gcc correctly warns about these.)
If paragraph 3 needs fixing in this regard, paragraph 10 probably
does, too.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 71.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.7
Title: typedef examples
Detailed description:
In example 2, it should really say "pointed to by a value of type
tp1" and "pointed to by a value of type tp2". (Also, should the
last "and" be "or"?)
In example 3, the construction "function returning signed
int with one unnamed parameter with type pointer to function
returning signed int with one unnamed parameter with type signed
int" is impossible to parse. Changing the end of it to "and
{having/accepting} one unnamed parameter with type signed int"
would help.
WG14: Response Code: E
-----------------------------------------------------------------
Comment 72.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.8
Title: the map is not the territory
Detailed description:
Paragraph 7 should end with "...the identifier shall name a
member of that type."
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 73.
Category: Inconsistency
Committee Draft subsection: 6.5.2.1 / 6.5.8
Title: vacuous unions
Detailed description:
Section 6.5.8, para. 9 says that "A union object containing only
unnamed members has indeterminate value even after initialization",
but section 6.5.2.1 says that such a union is undefined.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 74.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.8
Title: default initialization order
Detailed description:
Paragraph 19 says "written in increasing subscript or member
order", to which I would add "except as modified by any explicit
designators."
Paragraph 22 says "largest indexed element with an explicit
initializer" which I would change to something like "element with
the largest (explicitly or implicitly) indexed explicit
initializer".
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 75.
Category: Request for information/clarification
Committee Draft subsection: 6.5.8
Title: redundant initializers
Detailed description:
Is it forbidden to use designators to initialize multiple
elements of the same union? (For that matter, what happens
if a structure member or array element is multiply, explicitly
initialized?) Are the earlier initializers all "quietly
overridden" by the later, as in the discussion of example 11?
WG14: Response Code: Q
It is permitted to reinitialize the same element or
member of an array, structure or union. All such
initializers must be evaluated in lexical order.
See paragraph 14.
-----------------------------------------------------------------
Comment 76.
Category: Other (comment)
Committee Draft subsection:
Title: 6.6.4.2, 6.6.6.1
Detailed description:
Both sections prohibit jumping into blocks containing variably
modified types, and both sections use the word "shall" in a
constraint to do so. Therefore, a diagnostic is required.
Will the diagnostic be straightforward for the compiler to
generate?
WG14: Response Code: Q
The committee believes so and existing implementations
do so.
-----------------------------------------------------------------
Comment 77.
Category: Request for information/clarification
Committee Draft subsection: 6.6.6.1
Title: jumping past variably-modified declarations
Detailed description:
The wording in example 2 about "jumping past" a variably-modified
declaration is just different enough from the Standard's wording
that I'm suspicious that it says the same thing.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 78.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.6.6.4
Title: valueless return statements
Detailed description:
I don't think (what's left of) paragraph 4 is even necessary any
more; now that valueless return statements in non-void functions
are disallowed (i.e. by para. 1), the remaining undefined
behavior is adequately covered by the requirements that the type
of a called function match its definition.
I was surprised, though, that the other sentence, from the
1989/1990 version, of what's now paragraph 4 was deleted.
("Reaching the } that terminates a function is equivalent to
executing a return statement without an expression." I guess that
statement couldn't remain, though, given the other changes.)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 79.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: typo #2
Detailed description:
In para. 5, I believe the word "case" is missing between "in
which" and "there shall not be an identifier".
Also, since this clause is utterly significant, I don't think it
should be a parenthetical.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 80.
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.7.1
Title: old-style parameters shouldn't have to be declared
Detailed description:
The new requirement is imposed that "every identifier in the
[old-style] identifier list shall be declared." This is a
useless halfway stance between continuing to allow old-style
definitions and banning them outright. Since old-style
definitions do, in the general case, tend to omit explicit
declarations for parameters of type int, many of them will need
rewriting, but if the maintainers of old code are to be forced
to revisit those old-style definitions, they will surely take
the opportunity to update them completely to prototype style.
I appreciate the fact that an attempt is being made to do away
with default int, but the default should remain here. There is
no point in forcing implementors to emit new diagnostics, and
maintainers to rewrite new definitions, unless it's to go all
the way and retire the old-style definitions. If they're to be
retained at all, they might as well be retained in peace.
(Although I suppose that those old-style definitions without
explicit return types will need some revision, anyway.)
WG14: Response Code: N
The Committee discussed this proposal but decided
against it.
-----------------------------------------------------------------
Comment 81.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: redundant constraints on function compatibility
Detailed description:
Paragraph 8 seems redundant; functions without ellipses simply
don't accept variable numbers of arguments, per language
elsewhere.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 82.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: timing of conversions during function calls
Detailed description:
Paragraph 10 says that array and function arguments "are converted
to pointers before the call." This puts the horse behind the
cart; it should say "have already been converted to pointers (per
section 6.2.2.1)".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 83.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: parameter scope
Detailed description:
I think that the text of footnote 120 should be in the body of
the Standard; I'm not aware of this specific point being made
(explicitly or even implicitly) elsewhere.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 84.
Category: Request for information/clarification
Committee Draft subsection: 6.7.2
Title: default size of 1 for incomplete arrays?
Detailed description:
The assertion in example 2 that the array acquires a size of 1
took me by surprise. Is this fact implied by the words "with an
initializer equal to 0" in para. 2, or what?
WG14: Response Code: Q
Yes, you are correct.
-----------------------------------------------------------------
Comment 85.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.1
Title: semantics of #include semantics
Detailed description:
Since preprocessing arithmetic is essentially interpreted,
without benefit of any declarations, I think that the first two
instances of the word "types" in para. 3 should be replaced by
"values".
Also, the word "subclause" is missing before "6.4", and the
antecedent of the pronoun "this" in "This includes
interpreting..." is vague.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 86.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.2
Title: h vs. q char sequences
Detailed description:
Where paragraph 3 describes the fallback search, I think it
should say
... reprocessed as if it read
# include <q-char-sequence> new-line
(especially since it is explicitly specified that contained >
characters are retained).
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 87.
Category: Normative change to intent of existing feature
Committee Draft subsection: 6.8.3
Title: empty variable-length macro argument lists
Detailed description:
This has certainly been thought about by more minds than mine,
and there may well be issues I'm unaware of, but I'd say that the
variable-length part of a variable-length macro argument list
ought, just like those for functions, to be allowed to be empty.
Therefore, I would change "more" in para. 4 to "at least as many",
and I would add "(if any)" after "the trailing arguments" in
para. 12.
WG14: Response Code: N
The words are as was intended. A macro can now have an empty
argument. For example:
#define M1(...)
M1()
results in 1 empty argument in the call. Similarly,
#define M2(x, ...)
M2(a,)
results in 2 arguments in the call, the second of which
is empty. Note that M2 cannot be called using
M2(a)
M2 must be called with at least one more argument that
is specified in the macro's definition, as required by
the current draft.
-----------------------------------------------------------------
Comment 88.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.3
Title: misc. wording suggestions re preprocessor macros
Detailed description:
The word "declared" in para. 6 seems wrong; macro parameters are
not formally declared. I'd just replace "uniquely declared"
with "unique".
It may be worth emphasizing (i.e. perhaps with a footnote) that
the rescanning mentioned in para. 9 will be during replacement,
*not* during definition!
In paragraph 10, the function-like macro itself is *not* similar
syntactically to a function *call*. I might replace "similar
syntactically" with "which will be invoked with a syntax similar".
The last sentence of para. 12 is hard to understand, until one
realizes that "the number of arguments" following merger" counts
"the variable arguments" as a single composite argument.
WG14: Response Code: E
-----------------------------------------------------------------
Comment 89.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.3.3
Title: misc. wording #4
Detailed description:
In para. 2, I'd add "of a function-like macro" after "in the
replacement list".
The large parenthetical in the middle of para. 3 is quite
awkward; I'd make it a sentence in its own right,
non-parenthesized.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 90.
Category: Request for information/clarification
Committee Draft subsection: 6.8.3.3
Title: restrictions on constructed tokens?
Detailed description:
Are there *any* restrictions on the tokens that can be
constructed using ##, other than that universal character names
are out? (If there are restrictions, it probably wouldn't be hard
to state them in terms of translation phases, because that's
where they'd arise.)
"The resulting token is available for further macro replacement",
but not as a macro parameter name, right?
WG14: Response Code: Q
There are no restrictions.
-----------------------------------------------------------------
Comment 91.
Category: Inconsistency
Committee Draft subsection: 6.8.3.3
Title: name of preprocessor concatenation operator
Detailed description:
The name "catenation operator" is used nowhere outside of
the examples.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 92.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.3.4
Title: misc. wording #5
Detailed description:
I would add the word "along" before "with all subsequent
preprocessing tokens of the source file", and I would set the
entire clause off with commas or by parenthesizing it.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 93.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.4
Title: line control syntax
Detailed description:
Shouldn't the syntax description in para. 4 should be
# line digit-sequence "s-char-sequence" [opt]
Or is the intent that an empty pair of quotes must remain if the
s-char-sequence is omitted? If so, shouldn't it be specified
whether the presumed source file name is set to null, or left
unchanged, in this case?
Also, could it be argued that #line should take a
q-char-sequence rather than s? I would think that the arguments
(e.g. possibly different treatment of \ in operating system
filenames) which caused the concept of q-char-sequence to be
introduced for #include would apply to #line as well.
(If there's any substance to this speculation, the category I've
given to this comment is wrong; it'd be a normative change.)
WG14: Response Code: EN
The case where the s-char-sequence is completely omitted is
covered in the previous paragraph.
-----------------------------------------------------------------
Comment 94.
Category: Other (comment)
Committee Draft subsection:
Title: #error wrinkles
Detailed description:
Is it worth a footnote to point out that
#error Hello, world!
will work, and that
#error "Hello, world!"
may get you more quotes in the output than you'd expected?
(Probably not.)
I've always thought that it would be nice to be clearer on
whether #error terminates translation, or perhaps to provide
two variants (one which does and one which doesn't), but now is
not the time to propose or discuss that.
WG14: Response Code: Q
The existing words say that the resulting text includes
the user-specified text, allowing implementations to add
quotes already.
Over the years there has been some discussion about
providing something like #warning that issues a message
and continues; however, this suggestion has never gathered
sufficient interest.
-----------------------------------------------------------------
Comment 95.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.6
Title: #pragma musings
Detailed description:
I'd add "the compiler or" after "translation to fail or".
I'm also puzzled why it's stipulated that macro replacement is
*not* performed. By analogy with #include and #line, it seems
that it should be, and it might even be useful.
WG14: Response Code: EY
Some standard pragmas contain identifiers like ON and OFF,
which are likely to be defined as macros.
-----------------------------------------------------------------
Comment 96.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.8
Title: predefined macro names (wording)
Detailed description:
It would be clearer if "and shall expand as indicated" were added
after "shall be defined by the implementation."
I'm not sure why the word "presumed" appears in __FILE__'s
description, and not __LINE__'s. (Also, it might be worth
explicitly noting that both of these are affected by #line).
The parentheticals in the descriptions of __DATE__ and __TIME__
are significant enough that they should not be; I'd replace
"source file (a character string" with "source file: a character
string". Also, does the locale for the asctime function's
creating of month names need to be specified?
The word "shall" in para. 4 is odd. Presumably section 6.8.8 is
complete, and all predefined macro names simply *do*, by
observation, begin with two underscores. Is para. 4 trying to
constrain implementation extensions, or state future
directions? (In either case, the intent should be made clear.)
WG14: Response Code: E
-----------------------------------------------------------------
Comment 97.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.8
Title: typo #3
Detailed description:
There's an obvious formatting problem in para. 2.
WG14: Response Code: EY
-----------------------------------------------------------------
PUBLIC REVIEW COMMENT #8
-----------------------------------------------------------------
-----------------------------------------------------------------
Comment 1.
Category: Request for information/clarification
Committee Draft subsection: 7.1.1
Title: multibyte string definition
Detailed description:
"Shift sequence" is defined in paragraph 7 in terms of "multibyte
string", but it's not obvious what a multibyte string is.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 2.
Category: Request for information/clarification
Committee Draft subsection: 7.1.2
Title: careful definitions of standard macros
Detailed description:
Paragraph 5 says that implementors must be careful with the
definitions of standard object-like macros, but shouldn't the
same thing be said about function-like macros?
WG14: Response Code: Q
This is covered in 7.1.4, para. 1.
-----------------------------------------------------------------
Comment 3.
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.1.3
Title: new reserved identifiers
Detailed description:
Would it be at all practical to arrange that identifiers with
external linkage defined by this draft but *not* reserved by the
1989/1990 version, not be reserved unless their associated
headers are included? Otherwise, there are quite a number of
new "quiet changes." (As but one example, I suspect that many,
many windowing libraries already define a function wprintf for
formatted output into a window.)
WG14: Response Code: N
The functions to which you refer were added some
years ago by Amendment 1, they are not new in this
revision of the standard.
-----------------------------------------------------------------
Comment 4.
Category: Request for information/clarification
Committee Draft subsection: 7.1.3
Title: VPR #1
Detailed description:
The reference to "that context" in para. 2 is exceedingly vague,
and I'm not sure what is meant.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 5.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.1.4
Title: function definition of errno
Detailed description:
To avoid possible confusion, I recommend that the hypothetical
function suggested by footnote 134 be named __errno, or
_errno_function, or something. (Yes, I know, expansion of a
particular macro isn't recursive, but still.)
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 6.
Category: Other (comment)
Committee Draft subsection: 7.1.6
Title: multiply defined standard typedefs
Detailed description:
Does an explicit statement need to be made (e.g. in a footnote)
that "multiply defined" diagnostics for types such as size_t
are guaranteed not to occur even if several different headers
that define them are included?
WG14: Response Code: N
It is clear that a typedef name cannot be redefined,
so the implementation must define names such as size_t
once only even if multiple headers capable of defining
that name are included. It has to be made to work by the
implementor such that the programmer need take no special
action.
-----------------------------------------------------------------
Comment 7.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.1.8
Title: more global caveats
Detailed description:
I would add another general stipulation to the "Use of library
functions" section, which although it is stated or implied
elsewhere, seems well worth placing up front:
When a function involves the copying of data, if the
destination object or array is not big enough to hold
the copied data, or if copying takes place between
objects that overlap [*], the behavior is undefined.
[* Footnote: since most library functions are not to
be used to copy between overlapping regions, their
pointer parameters are qualified with restrict.]
(If placed here, the wording about "copying takes place between
objects that overlap" can be removed from many individual
function descriptions. It must be the case that they don't all
need individual explicit statements, because not all of them have
it now.)
Also, to the parenthetical list of invalid values at the
beginning of para. 1, I would add "or a pointer to a non-string".
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 8.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.2.1.1
Title: required information for assert's diagnostics
Detailed description:
The identifier __func__ has been added to the list in para. 2,
making the words "the latter" wrong unless the words "the current
function" are added somewhere before it.
An example implementation would be nice, too.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 9.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.3.1.3
Title: typo #1
Detailed description:
There's an extra "for" in the first sentence of para. 2.
Also, the comma after "set of characters" is unnecessary, and the
words "the following:" get in the way, and could be removed.
WG14: Response Code: SD
isblank and iswblank were not approved and should not have
appeared in the draft.
-----------------------------------------------------------------
Comment 10.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.3.1.7, 7.3.1.11
Title: misc. wording #1
Detailed description:
Like section 7.3.1.2, sections 7.3.1.7 and 7.3.1.11 should
reference footnote 146.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 11.
Category: Other (comment)
Committee Draft subsection: 7.3.2
Title: "corresponding" characters?
Detailed description:
Does the word "corresponding", as appearing in secs. 7.3.2.1 and
7.3.2.2, need any definition?
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 12.
Category: Request for information/clarification
Committee Draft subsection: 7.4
Title: "suitable character constants"?
Detailed description:
What are the "suitable character constants" defined by macros in
<inttypes.h>, if not formatted I/O conversion specifiers?
Was this meant to say "suitable integer constants", e.g. INTMAX_C?
WG14: Response Code: SD
The draft has been reworked in this area.
-----------------------------------------------------------------
Comment 13.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.4.5
Title: misdirected footnote?
Detailed description:
I doubt that para. 1 was meant to refer to footnote 151;
footnote 150, perhaps.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 14.
Category: Normative change to intent of existing feature
Committee Draft subsection:
Title:
Detailed description:
As I have said with respect to section 5.2.4.1, requiring all
implementations to support 65536-byte objects has potentially
serious effects on those with only 16 bits efficiently available.
I recommend requiring only 32767 as the minimum maximum values of
PTRDIFF_MIN, PTRDIFF_MAX, and SIZE_MAX.
WG14: Response Code: N
A 16-bit implementation can support 64K-sized objects.
The type ptrdiff_t need not be able to store all pointer
differences, however, size_t can, as can the macros.
-----------------------------------------------------------------
Comment 15.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.4.6
Title: typo #2
Detailed description:
A comma is missing after the word "performed" in the second
sentence of para. 1 in sec. 7.4.6.1, and in the same sentence
cut-and-pasted into secs. 7.4.6.2-7.4.6.4.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 16.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.5
Title: typo #3
Detailed description:
In para. 2, I believe it should say "*are* explained in
[section/subclause] 7.5.2.1."
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 17.
Category: Request for information/clarification
Committee Draft subsection: 7.5.2.1
Title: localized characters or strings
Detailed description:
Since decimal_point, thousands_sep, et al. are described as
being "characters", it might be nice to explain why they are
declared as being multi-character strings. Is it so that they
can be multibyte sequences?
(Also, some descriptions, e.g. mon_decimal_point's, seem to be
missing the word "character" or "string".)
Are the members having to do with formatted monetary quantities,
and which do not explicitly specify "internationally" or
"locally", applicable to both, or just locally-formatted
quantities?
WG14: Response Code: Q
Apparently some cultures use multiple characters.
The inconsistency regarding the use of character
and string is a hold-over from the previous standard.
Editorial changes have been to accomodate some of
your suggestions.
-----------------------------------------------------------------
Comment 18.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.5.2.1
Title: struct lconv: grouping and mon_grouping
Detailed description:
Paragraph 4 might rate a footnote pointing out that these are
integer values, *not* characters, that you want 3 or '\3' (not
'3') to specify a grouping of 3, and that the objects pointed to
by grouping and mon_grouping are *not* necessarily
null-terminated, nor are they in fact proper strings at all.
WG14: Response Code: CE
Note that grouping and mon_grouping *are* strings and require
proper termination.
-----------------------------------------------------------------
Comment 19.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.6
Title: "the arithmetic"
Detailed description:
Two instances of "the arithmetic" in para. 1 read awkwardly,
because we and this arithmetic haven't been properly introduced.
I'd suggest replacing both with "floating-point arithmetic".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 20.
Category: Other (comment)
Committee Draft subsection: 7.6.2.5
Title: misc. wording #2
Detailed description:
I found the appearance of "bitwise OR" in the "Returns" clause
(para. 3) momentarily confusing, because I'd think of the function
as returning "the bitwise AND of the masks of currently set and
queried exceptions".
WG14: Response Code: Q
The committee thinks the text is clear on this issue.
-----------------------------------------------------------------
Comment 21.
Category: Other (comment)
Committee Draft subsection: 7.6.3.2
Title:
Detailed description:
If it were like any of the other "set" functions in the standard
library, fesetround would return not only a nonzero value, but
the value of the previous mode. Would that be an option here?
(I know nothing of IEC 559, so perhaps not.)
Also, the description of the example refers to possible failure
of the setting of the rounding direction, but there are two
attempts to set; I'd say "...if setting the first rounding
direction" or "if the first set of the rounding direction".
WG14: Response Code: PA and CE
Part A: Although this approach could work, it conflicts
with too much prior art in this area.
Response: PA
Part B: The committee believes it is clear enough that
the first fesetround implements the "set" which
is being checked for failure and the second
fesetround implements the "restore".
Response: CE
-----------------------------------------------------------------
Comment 22.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7
Title: weak xref
Detailed description:
"later" at the end of para. 1 is weak; why not say "in subclause
7.14.6" (if that's in fact where you had in mind)?
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 23.
Category: Other (comment)
Committee Draft subsection: 7.7
Title: compile-time floating constant overflow?
Detailed description:
With respect to para. 4: As I have commented elsewhere, section
6.1.3.1 does not say as much as it might about floating-point
constant overflow.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 24.
Category: Request for information/clarification
Committee Draft subsection: 7.7
Title: Where is NAN?
Detailed description:
I can't find the description of the NAN macro. From reference
to it in sec. 7.7.11.12 and elsewhere, I learn that it might be
function-like, but I expected to see a formal statement to that
effect somewhere, probably in a distinct subclause for the NAN
macro. (If there is to be no such subclause, words could be
added to para. 5.)
WG14: Response Code: Q
The "NAN" macro is described in paragraph 5 and is
_not_ a function-like macro. The example in the
"nan" function description shows a string literal
argument to the "strtod" function. This is not
directly related to the "NAN" macro.
-----------------------------------------------------------------
Comment 25.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7
Title:
Detailed description:
I think the word "that" is missing in para. 7: "...indicates that
the fma function...".
Describing FP_FAST_FMAF and FP_FAST_FMAL as simply "analogs" is a
little weak; if I wanted to be formal and pedantic I'd say they
"describe, in the analogous way, { the behavior of / whether }
the fmaf and fmal functions { are faster } than multiplies and
adds of float and long double operands, respectively.
WG14: Response Code: EY and CE
-----------------------------------------------------------------
Comment 26.
Category: Other (comment)
Committee Draft subsection: 7.7
Title:
Detailed description:
In para. 9, a sentence or footnote relating DECIMAL_DIG to
FLT_DIG, DBL_DIG, and LDBL_DIG might be nice.
WG14: Response Code: Q
DECIMAL_DIG has been moved from math.h to float.h
and the relationship of these macros has been made
clearer.
-----------------------------------------------------------------
Comment 27.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7
Title: typo #4
Detailed description:
There may be a formatting problem in footnote 171.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 28.
Category: Request for information/clarification
Committee Draft subsection: 7.7.4.3
Title: atan(inf)?
Detailed description:
Should there be any mention of the result of taking the arc
tangent of an infinity, or are all such issues deferred to Annex F?
(I see that sec. F.9.1.3 covers just the case I asked about.)
WG14: Response Code: Q
You have it right.
-----------------------------------------------------------------
Comment 29.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7.6.8
Title: one to the 177?
Detailed description:
The attachment of footnote 177 is *particularly* awkward --
can't it be placed somewhere else, e.g. after "function"?
(Or was this a deliberate application of the teaching of
Nicholas Vanserg, who advised that "The other side of
the asterisk gambit is to use a superscript as a key to 14
a *real* footnote. The knowledge seeker reads that S is -36.7
calories and thinks `Gee what a whale of a lot of calories,'
until he reads to the bottom of the page, finds footnote 14
and says, `oh.'"? ["Mathmanship", as reprinted in A Stress
Analysis of a Strapless Evening Gown, Prentice-Hall, 1963,
ISBN 0-12-852608-7])
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 30.
Category: Request for information/clarification
Committee Draft subsection: 7.7.6.11
Title: partly perplexed by logb
Detailed description:
What does "in the format of x" mean?
I would have had an easier time understanding this function if it
were explicitly stated, up front, that the base with respect to
which the exponent is extracted is FLT_RADIX.
The second sentence is awkward; I might replace "normalized; thus
for" with "normalized. For".
WG14: Response Code: AL and CE
Part A: Replacing "the format of x" with "floating-point
format" to be consistent with function "rint".
Response: AL
Part B: Current woding is clear enough.
Response: CE
Part C: Current woding is clear enough.
Response: CE
-----------------------------------------------------------------
Comment 31.
Category: Other (suggestion)
Committee Draft subsection: 7.7.8
Title: erfc example?
Detailed description:
I don't have time to do the math or the implementation just now,
but wouldn't a lovely example involving erfc be a function
returning normally-distributed random numbers?
WG14: Response Code: NI
You are correct that it would be a good example - time
permitting.
-----------------------------------------------------------------
Comment 32.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7.9.3, 7.7.9.4
Title:
Detailed description:
The description in sec. 7.7.9.3 involves a gratuitous forward
reference. Why not interchange 7.7.9.3 and 7.7.9.4, and reword
nearbyint's description to "The nearbyint function is
{ similar / equivalent } to the rint function, differing only
in that..."?
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 33.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7.9.6
Title: llrint: one more notch less equivalent
Detailed description:
To the description in para. 2, I would add: ", and the result is
unspecified only if outside the range of long long."
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 34.
Category: Other (comment)
Committee Draft subsection: 7.7.9.7, 7.7.9.8
Title:
Detailed description:
I notice that lround's return value is long int, and that round's
is not int but double. (There's a bit of invited confusion
lurking here.)
WG14: Response Code: PA
Too much prior art in this area.
-----------------------------------------------------------------
Comment 35.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7.9.9
Title: llround: one more notch less equivalent
Detailed description:
To the description in para. 2, I would add: ", and the result is
unspecified only if outside the range of long long."
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 36.
Category: Other (comment)
Committee Draft subsection: 7.7.10.3
Title: remquo: what's it for?
Detailed description:
remquo's definition strikes me as being very strange.
(Presumably there's some precedent in numerical work?)
3 seems woefully inadequate as the maximum guaranteed value for
n; I'd have expected 10 or 15.
Is the word "of" missing before "at least 3"?
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 37.
Category: Other (comment)
Committee Draft subsection: 7.8.2.24
Title: cexp example
Detailed description:
It occurs to me that it'd be cute to give an example showing
that cexp(3.14159 * I) is pretty close to 1. (Or is it -1?
It's been too long...)
WG14: Response Code: NI
Example is not needed.
-----------------------------------------------------------------
Comment 38.
Category: Inconsistency
Committee Draft subsection: 7.10
Title: setjmp: macro or not?
Detailed description:
Sec. 7.10 para. 3 says that it's unspecified whether setjmp is a
macro, but sec. 7.10.1.1 refers to it (four times) as one.
(Also 3 times in sec. 7.10.2.1 para. 4.)
WG14: Response Code: Q
References to macro is 7.13.1.1 do not supercede that
in 7.13. It is a style issue in the library section
that the draft refers to the macro X or the function
X, rather than just X.
-----------------------------------------------------------------
Comment 39.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.12.1.2
Title: va_arg *not* guaranteed to have type of next argument
Detailed description:
The first sentence of para. 2 could be very misleading!
I'd at least replace "argument" by "parameter", or perhaps
replace "has the type and value of the next... in the call"
with "fetches the value of the next argument in the call,
which is {assumed/asserted} to have type _type_."
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 40.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.1
Title: what if I don't *want* any tmpnam's?
Detailed description:
The usage of "shall" with respect to TMP_MAX (in para. 3) is
incorrect. "shall be generated" should be replaced by "shall be
generatable" or simply "can be generated".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 41.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.1
Title: I/O function classification
Detailed description:
The descriptions of the wide-character input and output functions
claim they are described in "these subclauses", but of course
they're described nowhere in 7.13, but rather in 7.19.
The description of the byte input/output functions might say
"functions described in these subclauses that perform bytewise
input/output".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 42.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.2
Title: internal vs. external representations
Detailed description:
Paragraph 2 might be more explicit in noting that it's only
internal to the program that a text line consists of "zero or
more characters plus a terminating new-line character".
I'd add the words "internal to the program" (and perhaps even
refer to the "abstract machine") somewhere in the first sentence,
and add the word "external" before "host environment".
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 43.
Category: Other (comment)
Committee Draft subsection: 7.13.5.2
Title: misc. wording #3
Detailed description:
Why is there a forward reference to 7.13.7.11?
WG14: Response Code: E
-----------------------------------------------------------------
Comment 44.
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.13.5.3
Title: additional fopen modes
Detailed description:
I think that the behavior for mode strings other than those
listed should be implementation-defined, not undefined.
WG14: Response Code: N
-----------------------------------------------------------------
Comment 45.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.1
Title: fprintf description
Detailed description:
Paragraph 3 should be rewritten to use these sentences, adapted
from 7.19.2.1, which are nice in and of themselves, and which
must be moved here if my suggestion (see comment 95) to have
7.19.2.1 refer to 7.13.6 is adopted.
The processing of conversion specifications is as if
they were replaced in the format string by strings
that are each the result of fetching zero or more
subsequent arguments and converting them, if applicable,
according to the corresponding conversion specifier.
The expanded string is then written to the output stream.
Section 7.9.2.1 uses present tense rather than 7.13.6.1's future
perfect, and I think the former is preferable. I'd change each
instance of "will be" to "is", "will begin" to "begins", "will
have" to "has", and "will contain" to "contains".
The subparagraph in sec. 7.13.6.2 para. 3 about size modifiers is
somewhat nicer; if I had time, I'd try to fold some of it into
7.13.6.1. Also, I'd change two instances of "the argument will
have been promoted... and its value shall be converted to" to
"...but its value shall be converted back to".
In the description of %g, I'd add "unless the # flag is
specified" after "Trailing zeros are removed from the fractional
portion of the result".
With respect to paragraph 8, presumably a pointer to an array of
integral type is as acceptable for %n as an array of char is
for %s.
Paragraph 14's wording is unnecessarily evocative of
sec. 5.2.4's, and reads badly here. I'd simply say
"An implementation shall be able to support at least 4096
characters as produced by any single conversion" or
"If the number of characters produced by any one conversion
exceeds 4096, the results are undefined."
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 46.
Category: Inconsistency
Committee Draft subsection: 7.13.6.1
Title: printf %hhn ?
Detailed description:
The description of %n in para. 6 mentions the possibility of
%hhn, but the subparagraph about the n modifier in para. 3
does not.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 47.
Category: Other (comment)
Committee Draft subsection: 7.13.6.1
Title: printf format for complex
Detailed description:
Shouldn't there be a new printf (and scanf) format specifier for
the new complex types?
WG14: Response Code: Q
These were intentionally not provided, to print a
complex number you must extract and print its real
and imaginary parts indidually.
-----------------------------------------------------------------
Comment 48.
Category: Other (comment)
Committee Draft subsection: 7.13.6.1
Title: %a: any intellectual property problems?
Detailed description:
Using a formatted hexadecimal floating point representation is
an idea I've had for a long time but have never found time to
pursue; I'm delighted that the committee has introduced the %a
formats. However, I was dismayed a few years ago to hear that
IBM had somehow secured a patent on some variant of the same idea.
Is there any chance that all implementors will end up owing IBM
royalties for their (C9X-mandated) implementations of %a?
WG14: Response Code: Q
We are not aware of any intellectual property ownership
issues in this regard.
-----------------------------------------------------------------
Comment 49.
Category: Other (comment)
Committee Draft subsection:
Title: precision for %ls
Detailed description:
I suppose at one point it might have been an open question
whether a precision specifier within %ls should count wide
characters read from the source array or multibyte character
bytes written to the output stream. Since much code is thinking
more about the number of things being read from the array than
the number of things being written to the stream, and since the
count of bytes written ends up being so ambiguous (due to the
possibility, though denied, of partial multibyte sequences), I'd
say that it would have been better to specify the precision as
counting source wide characters, but I suppose it's too late now.
WG14: Response Code: BE
Yes, it is.
-----------------------------------------------------------------
Comment 50.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.1
Title: fprintf examples
Detailed description:
The word "this" in para. 16 is misleading; at first I assumed it
referred to the example I'd just read. It should either say
"the next example", or the examples should be numbered (as they
are in several other sections).
I found the second example nearly impossible to understand for
quite some time, until I realized that the notation "$0" was
intended to refer to one byte. (Yes, para. 16 can and should be
read to suggest otherwise, but I assumed that the $ was some
kind of shift sequence. We are, after all, talking about
multibyte sequences here.) I strongly suggest that a single
character be used, either @ or some non-ASCII glyph. (If there
was a taboo against using non-ASCII glyphs, the examples in sec.
7.13.6.2 have broken it.)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 51.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.2
Title: fscanf wording
Detailed description:
Paragraph 3 is awkward; I'd add ", each of which is either: a
sequence of" between "zero or more directives" and "one or more
white-space characters".
There's an extra "or" between l and ll in the first word of the
third bullet item in para. 3.
The singular/plural games in para. 6 are distracting. Is the
reason for talking about characters plural being read from the
stream that it might take several of them to match one
(multibyte) character in the format string?
The statement that a result is placed in "the object pointed to
by the first argument following the format argument that has not
already received a conversion result" is cumbersome and awkward,
and seems as if it would be necessary only in the case of the
numerically tagged specifiers which I've heard rumor that System
V supports. Here, wouldn't it be easier just to talk about "the
next argument"? (The description of fprintf seems to get by
without any of this.)
In the description of %f et al., "constant" should be changed
to "number" and "string" should be changed to "sequence" (if for
no other reason than that these are the words that sec. 7.19.2.2
uses).
In the second subparagraph describing %[, a subparagraph break
before "the conversion specifier includes" would help.
In paragraph 14, the parenthetical should be changed to "(other
than %n, if any)" (for consistency with fwscanf sec. 7.19.2.2).
I don't find the first sentence of footnote 218 implied anywhere
in the Standard; I'd like to see it moved there.
Should the last sentence of the Returns section (para. 17)
say "...in the event of early matching or input failure"?
(If so, all of the descriptions of the *scanf and *wscanf
functions are affected.)
WG14: Response Code: E
-----------------------------------------------------------------
Comment 52.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.2
Title: fscanf examples
Detailed description:
Shouldn't the first paragraph of the examples get a new
paragraph number?
The parallelism in the description of example 1 is quite poor;
I'd replace "name will contain thompson\0" with "to the array
name the string "thompson"".
*Please* don't use feof in this Pascalish way in example 3!
Either use fscanf's return value somehow (since it's being
carefully saved, although currently not otherwise used), or
retain feof/ferror, but in a do/while loop.
The construction "the stdin stream contains" is awkward;
I'd say "If the following lines are available on stdin".
In (the awkwardly numbered) paragraph 18, "these" is again
misleading, and should be replaced with "the following".
Also, a one-character glyph such as @ or some non-ASCII
character should again be used instead of $0.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 53.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.5
Title: sprintf wording
Detailed description:
The placement of the clause "rather than to a stream" in para. 2
is awkward; it seems to attach to "the argument s", not "an array".
I'd reword it thus:
...except that the output is written to the string s,
rather than to a stream.
Also, I'd replace "returned sum" with "returned character count".
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 54.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.6
Title: snprintf
Detailed description:
Hooray! This was the single greatest gaping need in the old
standard; I'm overjoyed to see it introduced here. I'd make the
first change suggested in comment 53 here too, though.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 55.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.7
Title: sscanf wording
Detailed description:
I'd reword the first sentence in para. 2 to end with
"...except that the input is read from the string s,
rather than from a stream."
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 56.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.8 et al.
Title: vfprintf wording
Detailed description:
I'd change "(and possibly subsequent va_arg calls)" to
"(and possibly {modified/affected} by subsequent va_arg calls)".
If you agree, the change should be made to all of the v*printf
and v*scanf descriptions (including those in sec. 7.19.2).
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 57.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.10, 7.13.6.11
Title: typo $5
Detailed description:
In these sections (and a large number of other sections), the
sentence "If copying takes place between objects that overlap,
the behavior is undefined" should probably be removed." It's true
in more sections than it appears, but since it appears in so many
of them, someone might get the impression that it *doesn't* apply
where it doesn't appear. Rather than repeating it ad nauseum,
it should be stated up front in section 7.1.8, with the restrict
qualifiers in the individual function descriptions serving as a
reminder.
WG14: Response Code: AN
-----------------------------------------------------------------
Comment 58.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.12, 7.13.6.13, 7.13.6.14
Title: typo #6
Detailed description:
In each section, the word "function" is missing before "does not
invoke the va_end macro".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 59.
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.13.7.2
Title: array contents after fgets error
Detailed description:
I'd say that "indeterminate" is too strong a statement on the
undefinedness of the array contents after error. Realistically,
each element of the array will either contain some character
read before the error occurred, or some character that was there
before fgets was called. There seems no chance of a read error
causing the sorts of "taboo" bit patterns to occur that the term
"indeterminate" tends to suggest. I'd say that the array
contents after error ought to be defined as unspecified.
(If by chance you agree, the same change should presumably be
made to gets sec. 7.13.7.7, although anyone who call gets deserves
whatever he gets.)
WG14: Response Code: N
Indeterminate indicates the same level of reliability
as does unspecified. In the interest of retaining the
same definition as ISO 9899:1990, no change will be
made.
-----------------------------------------------------------------
Comment 60.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.7.3
Title: fputc in append mode
Detailed description:
In para. 2, near the existing wording "at the position indicated
by the associated file position indicator for the stream (if
defined)", don't some words need to be added along the lines of
"or at end-of-file if the stream was opened in "a" mode"?
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 61.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.8.1
Title: fread "elements" undefined
Detailed description:
The descriptions of both fread and fwrite refer to "elements"
read or written, but this term (with this usage) is nowhere
defined. Use of it only suggests that the functions might
somehow treat array elements specially, e.g. by byte-swapping
the elements of an array of int appropriately (though how the
functions could ever know what swapping might be appropriate is
of course indeterminable).
Either the term "element" needs to be specifically defined as
"an array of unsigned char of size size", or the descriptions
need to be rewritten to use "bytes" instead of "elements".
For example:
The fread function reads, into the array pointed to by
ptr, up to nmemb*size bytes from the stream pointed to
by stream. The file position indicator for the stream
(if defined) is advanced by the number of bytes
successfully read. If an error occurs, the resulting
value of the file position indicator for the stream is
indeterminate. If the number of bytes successfully read
is not a multiple of size, the value of the last block
of size bytes is indeterminate.
Returns
The fread function returns the number of bytes
successfully read, divided by size, which may be less
than nmemb if a read error or end-of-file is encountered.
If size or nmemb is zero, fread returns zero and the
contents of the array and the state of the stream
remain unchanged.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 62.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.8.2
Title: fwrite "elements" undefined
Detailed description:
See the discussion under comment 61.
My suggested rewrite is
The fwrite function writes, from the array pointed to
by ptr, up to nmemb*size bytes to the stream pointed
to by stream. The file position indicator for the stream
(if defined) is advanced by the number of bytes
successfully written. If an error occurs, the resulting
value of the file position indicator for the stream is
indeterminate.
Returns
The fwrite function returns the number of bytes
successfully written, divided by size, which will be less
than nmemb only if a write error is encountered.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 63.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.9.1
Title: fgetpos description
Detailed description:
The file position indicator is of course no longer the only
information stored. I would change
...the current value of the file position indicator
for the stream pointed to by stream in the object...
to
...the current value of the file position indicator
and the mbstate_t object for the stream pointed to
by stream into the object...
or simply
...information about the current state of the stream
pointed to by stream, including the file position,
indicator [and the mbstate_t object], into the object...
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 64.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.9.2
Title: fseek wording
Detailed description:
In para. 2, "If a read or write error occurs" should be replaced
with "If an error occurs".
In para. 5, some words could be added (analogous to those in
7.13.9.3 para. 3) about a change from reading to writing, or
vice versa, now being possible for "r+", "w+", and "a+" streams.
WG14: Response Code: E
-----------------------------------------------------------------
Comment 65.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.9.3
Title: fsetpos wording
Detailed description:
In para. 2, "If a read or write error occurs" should be replaced
with "If an error occurs".
In para. 3, I'd add ", resets the mbstate_t object for the
stream to that saved in *pos," before "and undoes any effects
of the ungetc function on the same stream".
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 66.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.1.3, 7.14.1.4
Title: atol/atoll description discrepancy
Detailed description:
The descriptions (paras. 2) of atol and atoll are curiously
different. Is there any intent?
WG14: Response Code: E
-----------------------------------------------------------------
Comment 67.
Category: Request for information/clarification
Committee Draft subsection: 7.14.1.5
Title: strtod description
Detailed description:
Do the words "but no floating suffix" in para. 3 apply to all
the bullets above? I assume so, in which case I would replace
the fragment with "In no case is a floating suffix expected or
accepted in the subject sequence."
WG14: Response Code: E
-----------------------------------------------------------------
Comment 68.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.1.6, 7.14.1.7
Title: typo #7
Detailed description:
In both descriptions, "expect" should be replaced by "except that".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 69.
Category: Request for information/clarification
Committee Draft subsection: 7.14.1.7
Title: strtold precision
Detailed description:
Does the vague wording "similar to the strtod function"
adequately imply the function's presumably superior ability to
accurately reflect converted strings with large numbers of
significant digits?
WG14: Response Code: E
The descriptions of strtof and strtold have been
combined into a single subsection resulting in
the text in question's being removed.
-----------------------------------------------------------------
Comment 70.
Category: Request for information/clarification
Committee Draft subsection: 7.14.1.8
Title: strtol: null required?
Detailed description:
Paragraph 1 suggests that the final string includes the
terminating null character; does this mean that
char x[3] = "12x";
(void)strtol(x, NULL, 10);
is undefined?
WG14: Response Code: Q
Yes; the argument must be a string.
-----------------------------------------------------------------
Comment 71.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.1.8
Title: strtol wording
Detailed description:
For consistency with wcstol, in para. 3, add "(inclusive)" after
"base is between 2 and 36", change "10 to 35" to "10 through 35",
and add "and digits" before "whose ascribed values are less".
Also, add "subclause" before "6.1.3.2" in para. 5.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 72.
Category: Feature that should be included
Committee Draft subsection: 7.14.1.10
Title: strtoi
Detailed description:
Given that strtof has been added, I believe that strtoi should
be, as well.
WG14: Response Code: N
strtof was added to support correctly rounded results
for float that would not otherwise occur with strtod.
Since strtol and strtoul subsume completely int and
unsigned int conversion, the committee sees no need
to provide strtoi and strtoui.
-----------------------------------------------------------------
Comment 73.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.1.10
Title: strtoul wording (too much of)
Detailed description:
Given that strtoul's description is nearly identical to
strtol's, it could (and I think should) be replaced with
The strtoul function is equivalent to the strtol
function, except that the return value is type
unsigned long int.
That's really the *only* difference, other than the Returns
section, which would be given separately and explicitly, anyway.
My justification for the simplification is on general grounds
of parsimony, and also to make it easier for a reader to verify
that the two functions are, in fact, nearly identical.
I happen to have access to this draft in electronic form and to
a word-based diff program, but many readers will have neither.
(As a matter of fact, I think there should be a second and more
significant difference, namely that strtoul should not accept a
minus sign, but I guess it's too late for that now.)
If strtoul's text is not coalesced with strtol's, the exact same
comments as given above in comments 70 and 71 apply.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 74.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.2.1
Title: rand recommended practice
Detailed description:
Given that other sections have broken the ice on "Recommended
Practice" subsections, I would really love to see one for rand,
encouraging implementors to use an implementation (such as the
example in sec. 7.14.2.2) which allows users to take rand() % n
with decent results.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 75.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.3
Title: malloc recommended practice
Detailed description:
It would be nice to see some recommended practice here as well.
I would recommend three:
Whether or not free is explicitly called, all allocated
memory is reliably freed at program exit.
Space allocated by malloc is guaranteed to be available
to the program; no exceptions will result when the
program access the memory.
Whether freed memory is returned to an underlying
operating system and therefore made available to other
programs, or merely made available for future allocation
by the same program, is unspecified.
The second point obviously rules out "lazy allocation" schemes.
The third makes it explicit that returning freed memory to the
operating system is a valid possibility; I have heard it argued
that it somehow is not under the current C Standard.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 76.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.3.1
Title: calloc definition
Detailed description:
I think it is safer to define calloc as being equivalent to
malloc(nmemb * size)
rather than risking misinterpretations about "arrays" and
"objects" (see also comment 61). Also, the "all bits zero"
initialization could of course be succinctly defined in
terms of memset.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 77.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.3.4
Title: realloc description
Detailed description:
I'd say that the last sentence of the Returns section (para. 3)
should be moved to the formal description in para. 2, along with
an explicit statement that the former values of both ptr and
*ptr are then indeterminate.
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 78.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.4.1
Title: abort description
Detailed description:
The words "An implementation-defined form of the status
unsuccessful termination is returned to the host environment by
means of the function call raise(SIGABRT)" could be interpreted
as a recommendation to the programmer of how to get that result,
*as opposed to* whatever it is that abort does. I would change
"by means of the function call" to "as if by a call to".
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 79.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.5
Title: searching/sorting wording
Detailed description:
In para. 3, it is presumably the implementation *of qsort* which
may reorder elements of the array, not the comparison function
of the preceding sentence (nor bsearch).
I would use plural in para. 4:
When the same objects (consisting of size bytes,
irrespective of their current position in the array)
are passed more than once...
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 80.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.5
Title: qsort/bsearch example
Detailed description:
An example might be nice:
After declaring
char *sarray[100];
int pstrcmp(const void *p1, const void *p2)
{
return strcmp(*(char * const *)p1, *(char * const *)p1);
}
and after filling in the array sarray with 100 pointers to
strings, the call
qsort(sarray, 100, sizeof(char *), pstrcmp)
will sort them, and the call
char *p = bsearch("test", sarray, 100, sizeof(char *), pstrcmp);
will search for the string "test".
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 81.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.6.2
Title: div wording
Detailed description:
I would replace "of the division" with "resulting from the
division", and I might add "If denom is 0 or" before "if the
result cannot be represented."
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 82.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.15
Title: centralized non-overlap wording
Detailed description:
If the undefinedness of copying between overlapping regions
is asserted just once, up front (see comment 7), it could
be removed from the individual subsections of this section.
WG14: Response Code: AN
-----------------------------------------------------------------
Comment 83.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.15.5.7
Title: typo #8
Detailed description:
A period is missing at the end of para. 2.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 84.
Category: Feature that should be included
Committee Draft subsection: 7.15.5.8
Title: safer strtok
Detailed description:
Following the precedent set by wcstok (sec. 7.19.4.5.7), there
should really be a strtok variant (some implementations call it
strtok_r) which accepts a pointer to the pointer storage to be
used between calls.
WG14: Response Code: N
When wcstok was added, it was given more capability
than existed in strtok. However, the committee has
decided against provided equivalent support in
an extended version of strtok.
-----------------------------------------------------------------
Comment 85.
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.16.1
Title: tm_extlen default value
Detailed description:
Following the Internet rule of "Be conservative in what you
send, liberal in what you accept", I believe that tm_extlen
should be specified as being 0 if tm_ext is a null pointer
(para. 5). Leaving it unspecified buys nothing, and only
invites needless errors. (If this change is made, the lists
in Annex K will of course have to be updated.)
WG14: Response Code: N
-----------------------------------------------------------------
Comment 86.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.16.2.3
Title: mktime verbiage
Detailed description:
Paragraphs 5 and 6 repeat too much of paragraphs 3 and 4.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 87.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.16.2.4
Title: mkxtime wording
Detailed description:
In paragraph 2, "into account of" should be either "into account"
or "account of". Also, "of struct tmx" could be usefully added
at the end of that sentence.
In paragraph 3, "include the effects" should probably be
"including the effects".
There is no Returns section.
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 88.
Category: Other (comment)
Committee Draft subsection: 7.16.3.5
Title: misc. wording #4 (zonetime)
Detailed description:
More precisely, if the implementation cannot determine the
relationship between the implementation's time and the requested
zone. (Para. 2.)
(Also, the pronoun "that" in para. 3 is vague.)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 89.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.16.3.6
Title: strftime description
Detailed description:
The reason for the bracketed member names in the list of
conversion specifiers in para. 2 should be explained.
(Presumably they are the ones containing "values contained
in the structure" relevant to that specifier.) For %x and %X,
"[all specified in 7.6.1]" would more fully be "[all fields
specified in subclause 7.6.1]".
For %Z, I presume that the time zone name or abbreviation may be
locale-specific.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 90.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.18.2.1
Title: misc. wording #5
Detailed description:
I can't parse the first sentence of para. 2. I think what it's
trying to say is
For wide characters corresponding to regular characters,
and/but with the exception of..., each of the following
functions...
WG14: Response Code: E
-----------------------------------------------------------------
Comment 91.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.18.2.1.1
Title: typo #9
Detailed description:
Th first word of para. 2 is misspelled.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 92.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.18.2.1.3
Title: typo #10
Detailed description:
There's an extra "for" in the first sentence of para. 2.
Also, the comma after "set of characters" is unnecessary, and the
words "the following:" get in the way, and could be removed.
WG14: Response Code: SD
isblank and iswblank were not approved and should not have
appeared in the draft.
-----------------------------------------------------------------
Comment 93.
Category: Request for information/clarification
Committee Draft subsection: 7.18.2.1.0
Title: iswspace definition
Detailed description:
Saying "none of iswalnum, iswgraph, or iswpunct" seems redundant,
because I believe iswgraph tests for the union of iswalnum and
iswpunct. Also, the relationship (inclusive or exclusive) to
iswcntrl is not mentioned.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 94.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.1
Title: misc. wording #6
Detailed description:
In paragraph 10, there are now *two* functions for wide-string
date and time conversion.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 95.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.2.1
Title: fwprintf wording (too much of)
Detailed description:
Given that fwprintf's description is nearly identical to
fprintf's, it could (and I think should) be replaced with
The fwprintf function is equivalent to the fprintf
function (see section 7.13.6.1), except that:
the format string pointed to by fmt is a wide
character string;
the various characters expected in the format
string, and the characters written to the output
stream, are all wide characters;
wherever 7.13.6.1 refers to n-char-sequence,
fwprintf uses n-wchar-sequence;
[though there's no difference?]
for the %c format specifier, if no l qualifier
is present, the int argument is converted to a
wide character as if by calling btowc, and the
resulting wide character is written;
for the %c format specifier, if an l qualifier
is present, the wint_t argument is converted
to wchar_t and written; and
for the %s format specifier, the behavior/
description is [as now described in the working
draft section 7.19.2.1].
I believe that this list is complete, especially if the changes
suggested in comment 45 are incorporated.
See also my comment 73 for additional justification for this
change. (I might also point out that section 7.19.5 already uses
this sort of wording to define wcsftime in terms of strftime, so
there's a precedent.)
If fwprintf's text is not coalesced with fprintf's:
the extra sentence at the end of para. 2 should be
discarded;
the discrepancy (noted in comment 46) with respect to %hhn
should be rectified; and
the first paragraph under "Recommended practice" should be
numbered.
Also, I believe the example should be omitted; it is so similar
to fprintf's example that it serves no useful purpose.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 96.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.2.2
Title: fwscanf wording (too much of)
Detailed description:
Given that fwscanf's description is nearly identical to
fscanf's, it could (and I think should) be replaced with
The fwscanf function is equivalent to the fscanf
function (see section 7.13.6.2), except that:
the format string pointed to by fmt is a
wide character string;
the various characters expected in the
format string, and the characters read from
the input stream, are all wide characters;
the (optional) maximum field width in a
conversion specifier specifies a count of
wide characters;
a directive that is an ordinary wide character
[in the format string] is expected to match a
wide character read from the input stream;
input white-space characters (to be skipped in
response to white-space directives and before
conversion specifiers other than %[, %c, and %n)
are as specified by the iswspace function;
{ input performed by the %d and %i specifiers
is converted as if by a call to the wcstol
function / the input expected by the %d and %i
specifiers is of the same format as that expected
for the subject sequence of the wcstol function };
{ input performed by the %o, %u, and %x specifiers
is converted as if by a call to the wcstoul
function / the input expected by the %o, %u, and %x
specifiers is of the same format as that expected
for the subject sequence of the wcstoul function };
{ input performed by the %a, %e,, %f and %g
specifiers is converted as if by a call to the
wcstod function / the input expected by the %a, %e,
%f and %g specifiers is of the same format as that
expected for the subject sequence of the wcstod
function };
for the %[, %c, and %s format specifiers, the
behavior/description is [as now described in the
working draft section 7.19.2.2, or try to coalesce
if you like].
I believe that this list is complete.
See also my comment 73 for additional justification for this
change.
If fwscanf's text is not coalesced with fscanf's:
several of my suggestions from comment 51 apply
analogously;
the typo in the description of %[ should be fixed
("f no l qualifier is present"); and
the missing period at the end of %%'s description
should be supplied.
Also, I believe the examples should be omitted; they are so
similar to fscanf's examples that they serve no useful purpose.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 97.
Category: Other (comment)
Committee Draft subsection: 7.19.2.5
Title: swprintf confusion
Detailed description:
It was wrong to have given swprintf its current functionality
without naming it snwprintf or swnprintf, and the confusion is
compounded now that snprintf's return value is specified so
differently.
WG14: Response Code: CC
The committee agrees. We decided to `do it correctly'
with the new function and that does not match the
older function.
-----------------------------------------------------------------
Comment 98.
Category: Other (comment)
Committee Draft subsection: 7.19.3.1
Title: fgetwc description
Detailed description:
Is there anything to be said about the orientation (byte/wide)
of the stream? (Ditto, I suppose, for fputwc.)
WG14: Response Code: Q
The committee thinks not.
-----------------------------------------------------------------
Comment 99.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.3.9
Title: typo #11
Detailed description:
A close parenthesis is missing after the second instance of
"pointed to by stream".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 100.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.4.1.1
Title: wcstod wording (too much of)
Detailed description:
Given that wcstod's description is nearly identical to
strtod's, it could (and I think should) be replaced with
The wcstod function is equivalent to the strtod
function (see section 7.14.1.5), except that:
where strtod expects certain characters
(including those referred to in subclause
6.1.3.1), wcstod expects the corresponding
wide characters;
initial white-space characters (to be skipped)
are as specified by the iswspace function;
wherever 7.14.1.5 refers to n-char-sequence,
fwprintf uses n-wchar-sequence;
[though there's no difference?]
and
paragraphs 6 and 7 are swapped :-).
I believe that this list is complete.
See also my comment 73 for additional justification for this
change.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 101.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.4.1.1
Title: n-wchar-sequence definition
Detailed description:
Is the definition of n-wchar-sequence any different from
n-char-sequence? Also, these two sequences are missing from
Annex B.
WG14: Response Code: Q
Although the abstract semantics are the same, the types of
the characters are different (one is narrow, the other is
wide). They don't appear in annex B because they are not
part of the language syntax.
-----------------------------------------------------------------
Comment 102.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.4.1.4
Title: wcstol wording
Detailed description:
Given that wcstol's description is nearly identical to
strtol's, it could (and I think should) be replaced with
The wcstol function is equivalent to the strtol
function (see section 7.14.1.8), except that:
where strtol expects certain characters
(including those referred to in subclause
6.1.3.2), wcstol expects the corresponding
wide characters;
the various characters expected in the input
string are all wide characters; and
initial white-space characters (to be skipped)
are as specified by the iswspace function.
I believe that this list is complete.
See also my comment 73 for additional justification.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 103.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.4.1.6
Title: wcstoul wording
Detailed description:
Given that wcstoul's description is nearly identical to
strtoul's, it could at the very least be replaced with
The wcstoul function is equivalent to the strtoul
function (see section 7.14.1.10), except that:
where strtoul expects certain characters
(including those referred to in subclause
6.1.3.2), wcstoul expects the corresponding
wide characters;
the various characters expected in the input
string are all wide characters; and
initial white-space characters (to be skipped)
are as specified by the iswspace function.
I believe that this list is complete.
On the other hand, wcstoul could be defined even more succinctly
in terms of wcstol, analogous to my comment 73 (q.v. for more
justification for this suggestion).
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 104.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.4.6
Title: typo #12
Detailed description:
I believe a comment is missing after "affected by locale" in
para. 1.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 105.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.7
Title: misc. wording #7
Detailed description:
The parameter name ps appears in para. 4 out of a clear sky.
It could be introduced in para. 2: "...take as a last argument
a pointer, ps, to an object...".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 106.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.7.3.1
Title: typo #13?
Detailed description:
In paragraph 3, should the word "or" be inserted before "a value"?
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 107.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.7.3.2
Title: typo #14?
Detailed description:
In paragraph 4, ion the subparagraph for positive return,
I believe the comma should be a semicolon.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 108.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.19.7.4.1
Title: mbsrtowcs specification
Detailed description:
Should the src parameter have type const char * restrict * restrict?
In para. 2, should there be a comma after "pointed to by src"?
If an encoding error occurs, is the pointer pointed to by src
unchanged, unspecified, or undefined? (Para. 4).
These comments all apply to wcsrtombs (sec. 7.19.7.4.2), as well.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 109.
Category: Editorial change/non-normative contribution
Committee Draft subsection: Annex B
Title: n-char-sequence in syntax summary?
Detailed description:
As I've mentioned elsewhere, neither n-char-sequence
(sec. 7.14.1.5) nor n-wchar-sequence (sec. 7.19.4.1.1) appear.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 110.
Category: Editorial change/non-normative contribution
Committee Draft subsection: Annex C
Title: printf sequence points
Detailed description:
Section 7.13.6 implies that "there is a sequence point after the
actions associated with each specifier."
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 111.
Category: Request for information/clarification
Committee Draft subsection: Annex E
Title: misc. wording #8
Detailed description:
What are FLT_EVAL_METHOD and FLT_ROUNDS doing there between
paragraphs 2 and 3?
WG14: Response Code: E
-----------------------------------------------------------------
Comment 112.
Category: Editorial change/non-normative contribution
Committee Draft subsection: Annex I
Title: typo #15?
Detailed description:
My copy of Unicode spells Cyrillic with two l's.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 113.
Category: Editorial change/non-normative contribution
Committee Draft subsection: Annex J
Title: warnings about warnings
Detailed description:
I would *not* say that warnings about converting "a pointer to
void to a pointer to any type other than a character type" are
common. (It's C++ that requires casts on every call to malloc,
not C.)
Warnings about functions with return statements with and without
expressions should no longer be required, given that changes to
sec. 6.6.6.4 (I believe) make these errors now.
I'd say it's poor to warn about unrecognized pragmas.
WG14: Response Code: E
-----------------------------------------------------------------
Comment 114.
Category: Editorial change/non-normative contribution
Committee Draft subsection: K.2
Title: not-so-undefined behavior
Detailed description:
Many of the bullet items in section K.2 are strange, and do
not seem to correspond to language in the draft Standard.
Here are a few:
The first character of an identifier is a digit (6.1.2).
[not possible, I'd say]
The same identifier is used more than once as a label in the
same function (6.1.2.1).
[not possible, I'd say]
A trap representation is produced by a side effect that
modifies any part of the object by an lvalue expression that
does not have character type. (6.1.2.8.1).
[may be okay, but I can't parse it]
The whole-number and fraction parts of a floating constant
are both omitted (6.1.3.1).
The period and the exponent part of a decimal floating
constant are both omitted (6.1.3.1).
Conversion between two pointer types produces a result that
is incorrectly aligned (6.2.1.3).
[6.2.1.3 is about floating-point types; this identical text
appears 6 more bullets down under 6.2.2.3]
Non-integer operands are used with a bitwise operator (6.3).
WG14: Response Code: EY
-----------------------------------------------------------------
PUBLIC REVIEW COMMENT #9
-----------------------------------------------------------------
-----------------------------------------------------------------
Comment 1.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.1.1.1
Title: misc. wording #1
Detailed description:
The clause ", in this International Standard" in para. 1 is
extremely awkward, and invites being read as the place where
program text, source files, and/or preprocessing files are
stored. Rather than trying to reword or relocate the clause,
I'd say it could simply be omitted.
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 2.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.5
Title: misc. wording #2
Detailed description:
In the last sentence of para. 3, I'd omit the word "just".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 3.
Category: other (comment)
Committee Draft subsection: 6.1.2.5
Title: misc. wording #3
Detailed description:
The keyword `signed' appears out of a clear sky in para. 14,
somewhat awkwardly.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 4.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.2.5
Title: misc. wording #4
Detailed description:
It seemed to me that para. 19 belonged next to para. 14.
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 5.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.2.1.1
Title: confusing wording on promotable types
Detailed description:
In para. 3, the words "the original type" have a mildly vague
antecedent. They really mean "the type being used instead"
(although that wording's obviously worse).
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 6.
Category: Other (comment)
Committee Draft subsection: 6.2.2.2
Title: misc. wording #6
Detailed description:
I don't think there are any contexts where "a void expression is
required"; the likely candidates (secs. 6.3.17, 6.6.3, and
6.6.5.3) all merely say that the expression (of presumably any
type) is "evaluated as a void expression".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 7.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.2.2.3
Title: misc. wording #7
Detailed description:
In para. 7, "pointed-to type" (i.e. with an added hyphen) might
read more clearly.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 8.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.1.1
Title: misc. wording #8
Detailed description:
Please make sure (by using \^, or whatever) that the underscores
are distinct in the section head, table of contents, index, etc.,
as they are in the body of para. 1.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 9.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.2.1
Title: misc. wording #9
Detailed description:
The antecedent of the word "that" in "that in turn" is ambiguous.
(Is it "the results", the "array of five ints", or "the
expression x[i][j]"?)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 10.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.3.2.2
Title: misc. wording #10
Detailed description:
Paragraph 10's point would be made more strongly if it used
the words "actual arguments".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 11.
Category: Request for information/clarification
Committee Draft subsection: 6.3.3.3
Title: misc. wording #11
Detailed description:
Is "the integral promotion" singular now?
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 12.
Category: Other (comment)
Committee Draft subsection: 6.3.6
Title: misc. wording #12
Detailed description:
I have to say, those two parentheticals in paras. 2 and 3 sound
pretty retarded, and don't seem to add much.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 13.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.4
Title: misc. wording #13
Detailed description:
I'd find footnote 85 a bit clearer with the word
"initialization" or "initializing" inserted before "expression".
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 14.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.2.1
Title: misc. wording #14
Detailed description:
The words "of this" in para. 10 are awkward, and the pronoun has
no antecedent. I'd simply delete both words.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 15.
Category: Other (comment)
Committee Draft subsection: 6.5.2.1
Title: misc. wording #15
Detailed description:
A "flexible array member"?? (Para. 15.) I'm sorry, but I
suspect that most of us will continue to call it "the struct
hack" (or perhaps, "the new, legitimate struct hack").
WG14: Response Code: CC
-----------------------------------------------------------------
Comment 16.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.5.1
Title: misc. wording #16
Detailed description:
I might add "(which shall also not be modified)" at the end of
the sentence ending in "to point to another object" in the
example paragraph 3.
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 17.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.6
Title: misc. wording #17
Detailed description:
The word "desired" in para. 2 seems wrong; I might suggest
"necessary". Also, the second sentence is easy to misread --
it really needs parentheses for grouping, i.e. "a declaration
for (a function or an object) of that type". I'm not sure how
to fix it, although part of the problem is simply the use of
both indefinite articles.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 18.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.7
Title: misc. wording #18
Detailed description:
The construction "specifies the type specified" in para. 2 is
awkward, but I don't know how to fix it. I might add the word
"along" between "shall be evaluated" and "with the typedef name".
The construction "declared in ordinary declarators" reads badly;
I'd at least change it to "declared in ordinary declarations" or
"declared by ordinary declarators".
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 19.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.8
Title: misc. wording #19
Detailed description:
Paragraph 3 might read better with the alternatives interchanged:
The type of the entity to be initialized shall be
an object type that is not a variable length array type
or an array of unknown size.
I observe (though this probably doesn't ever rate a footnote)
that "object type that is not a variable length array type"
perforce includes arrays of known size.
In paragraph 6, is it obvious that "any nonnegative value is
valid" means only that it is syntactically valid, but that the
implementation might complain if a large value caused an object
to be too large?
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 20.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.8
Title: misc. wording #20
Detailed description:
"that member" in para. 13 has a vague referent.
Should the word "below" in para. 15 be "herein"?
In para. 20, "these rules" might be better than just "the rules".
WG14: Response Code: E
-----------------------------------------------------------------
Comment 21.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.5.8
Title: misc. wording #21
Detailed description:
In example 7, towards the end, I would change "that is
initialized" to "and initializes it".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 22.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.6.4.2, 6.6.6.1
Title: misc. wording #22
Detailed description:
The first sentence of section 6.6.4.2 para. 1 is pretty awful,
but I'm afraid I don't have any suggestions for fixing it.
Section 6.6.6.1 para. 1 isn't much better. In both sections,
removing the words "to a... statement... in the block (or an
enclosed block)" might help; these words add much to the
cumbersomeness and seemingly nothing to the meaning (i.e. my
reading of the paragraphs is the same with those words removed).
WG14: Response Code: SD
-----------------------------------------------------------------
Comment 23.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.6.6.1
Title: misc. wording #23
Detailed description:
Example 1 is a heroic attempt to make an example realistic, for
once, but I'm afraid it was lost on me. Jumping into blocks is
a capability that clearly exists but is just as clearly almost
always a bad idea; given those facts, I just couldn't motivate
myself to wrap my brain around the tortured justification, nor
(I think) would my understanding of the issue of jumping into
blocks have changed if I had. I'd omit that example.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 24.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: misc. wording #24
Detailed description:
The verb tenses in paragraph 10 are inconsistent. The three
instances of "shall be" clash with other instances of "are",
and should all be changed to "is" (unless the are's are changed
to shall's as well).
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 25.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.7.1
Title: misc. wording #25
Detailed description:
At the end of example 1, I'd say that the second form *does* not.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 26.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8
Title: misc. wording #26
Detailed description:
In the syntax description, I'd define `lparen' as "a left
parenthesis character not preceded by any whitespace."
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 27.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.8.3.2
Title: misc. wording #27
Detailed description:
In para. 1, I might replace "parameter" with "parameter name".
In para. 2, I might replace "between" with "within" or "among".
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 28.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.1.2
Title: misc. wording #28
Detailed description:
In para. 3, I'd replace "included" with "searched for".
The exception for <assert.h> in para. 4 is imperfectly worded.
What it's trying to say, of course, is that the effect of
including <assert.h> multiple times depends on the instantaneous
definition of the NDEBUG macro.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 29.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.1.6
Title: misc. wording #29
Detailed description:
In the description of offsetof, strictly speaking, what we need
is that the member-designator *and type* are such that...
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 30.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.4
Title: misc. wording #30
Detailed description:
At the end of para. 2, I'd say that *many* of these names *will*
denote the same type!
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 31.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.4.4
Title: misc. wording #31
Detailed description:
With respect to footnote 152, I'm not sure how typical it is for
printf and scanf format strings to be different; in my own work,
I try to keep them identical. I'd replace "typically" with "in
the general case", and "are required" with "may be required".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 32.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.7.3.5
Title: misc. wording #32
Detailed description:
I'd say that "doesn't" in footnote 176 should be spelled out.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 33.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.3
Title: misc. wording #33
Detailed description:
In para. 7, I'd say "As initially opened, the standard error stream..."
I think the word "nor" in the second bullet in para. 9 is wrong.
WG14: Response Code: E
-----------------------------------------------------------------
Comment 34.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.5.4
Title: misc. wording #34
Detailed description:
I'd delete the word "successfully" in para. 3 -- failure to close
the file unsuccessfully (or at all) is ignored, too!
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 35.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.1
Title: misc. wording #35
Detailed description:
I'd add the word "character after % in the description of the %%
specifier in para. 6. (For consistency with sec. 7.19.2.1, if
nothing else.)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 36.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.6.1
Title: misc. wording #36
Detailed description:
Towards the end of the description of %[, I'd change "the next
right bracket wide character is the matching right bracket that
ends the specification" to "the next following right bracket wide
character".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 37.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7/13/6/8
Title: misc. wording #37
Detailed description:
In footnote 219, I'd change "invoke" to "do invoke", and "after
the return" to "in the caller becomes".
WG14: Response Code: CE
-----------------------------------------------------------------
Comment 38.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.7.8
Title: misc. wording #38
Detailed description:
putc takes two arguments, so I would change "so the argument" in
para. 2 to "so that argument".
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 39.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.13.7.11
Title: misc. wording #39
Detailed description:
I'd change "The pushed-back characters" in para. 2 to either
"Pushed-back characters" or "The pushed-back character".
(I wonder why the plural was used at all, since multiple
characters of pushback are of course not guaranteed.)
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 40.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.1.5
Title: misc. wording #40
Detailed description:
In para. 4, two instances of "like a" are awkward; I'd replace
both with "as would be a".
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 41.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.2.2
Title: misc. wording #41
Detailed description:
I would change "a new sequence" to "the sequence" and
"the sequence of pseudo-random numbers shall be repeated"
to "the same sequence...".
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 42.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 7.14.5.2
Title: misc. wording #42
Detailed description:
In para. 4, I would say "in the resulting sorted array".
WG14: Response Code: EY
-----------------------------------------------------------------
PUBLIC REVIEW COMMENT #10
Comment 1.
Category: Editorial change/non-normative contribution
Committee Draft subsection: none
Title: Introduction to my comments on Draft C9X
Detailed description:
Here are some comments on Draft C9X from the point of view of a GCC
implementer. In the terminology of the standard, GCC is a
freestanding compiler, so I'm restricting most of these comments to
the compiler proper. I will ignore many of the changes in the
standard, as they affect the underlying C library but require no
changes to GCC itself. My current expertise is mostly in the
preprocessor area, so I'll focus in that area.
However, I've also implemented part of the <time.h> section of the GNU
C library, so I'll also comment on changes in that area.
WG14: Response Code: CC
-----------------------------------------------------------------
Comment 2.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.1.2, 5.2.1, 6.1.2, Annex I
Title: Universal Character Names (UCNs): the basic model is wrong
Detailed description:
Background
Draft C9X proposes a new notation (e.g. \u098a or \U0000098A) for
including arbitrary ISO 10646 (Unicode) characters in identifiers,
strings, and comments. They work as follows:
* In translation phase 1, each multibyte source file character is
replaced by the corresponding UCN. This occurs very early, even
before trigraph replacements.
* In translation phase 5 (just after preprocessing), UCNs in char
constants and string literals are converted to the execution
character set.
* Some UCNs are valid in identifiers, but not others. E.g.
\u098a (BENGALI LETTER UU) is valid, but
\u2110 (SCRIPT CAPITAL I) is not valid.
Problems
Here are some problems with UCNs as they appear in the current draft.
* The current draft assumes that source file characters can be
transliterated to Unicode and back again without loss of
information.
This assumption is incorrect and unrealistic. For example,
ISO-2022-JP
<ftp://ftp.isi.edu/in-notes/rfc1468.txt> cannot
be converted to Unicode without losing information.
As a trivial example, ISO-2022-JP distinguishes between `ESC
( B' (which switches to ASCII) and `ESC ( J' (which switches to
JIS-Roman); but Unicode discards the distinction between ASCII
and JIS-Roman for most characters, as it unifies most of the
characters in the two sets. This means that the C9X draft
effectively disallows the correct handling of ISO-2022-JP in
string literals; an ISO-2022-JP string that contains `ESC ( J'
is not guaranteed to contain the same `ESC ( J' after being
translated to Unicode and back again.
I believe that EBCDIC has a similar problem, as there are
multiple representations of `[' in EBCDIC but only one in
Unicode.
* The use of \u collides with common usage in include directives.
For example, `#include "h\ufeed.h"' must be treated
equivalently to `#include "[email protected]", where @ is Unicode character
FEED (ARABIC LETTER WAW ISOLATED FORM). This is not what the
programmer likely intended, and C9X must not require this weird
sort of case-folding.
* The current draft requires that the implementation maintain
translation tables from the source and execution character set
to Unicode, in order to properly stringize strings. This
requirement is unrealistic. Many environments are not using
Unicode yet, and do not have such tables. This problem is
particularly acute for portable compilers like GCC, as there
is no portable standard for accessing such transliteration tables.
* The current draft silently changes behavior when stringizing strings
that contain multibyte characters. For example, if @ represents
the Unicode character with code FEED (ARABIC LETTER WAW ISOLATED FORM),
then
#define str(s) #s
printf("\t# of <%s> is <%s>\n", "@", str("@"));
outputs something like this:
# of <@> is <"\ufeed">
whereas with C89 the program would output
# of <@> is <"@">
Clearly the C89 behavior is what is expected.
* The current draft precludes a simple implementation that simply
treats characters with the top bit on as letters. Such an
implementation supports popular encodings like UTF-8 and EUC
without having to know what the encoding is. However, the
current draft requires that the implementation convert each
character to Unicode, which means the implementation must
laboriously check for encoding errors, transliterate to and
from Unicode, and the like. It also means the user must
configure the compiler correctly, to specify which encoding is
desired.
* The list of UCNs allowed in identifiers is arbitrary and weird.
Although the standard seems to allow an implementation to permit
almost all UCNs in identifiers, this is not made clear.
Suggestion
Reword the standard so that UCNs are translated to the source
character set in translation phase 1, and are never seen again.
Allow an implementation-defined set of source characters in
identifiers, using the existing Annex I as a guideline.
More specifically, in Section 5.1.1.2 phase 1 change from:
Any multibyte source file character not in the basic
source character set is replaced by the
universal-character-name that designates that multibyte
character.
to:
Any universal-character-name is replaced by a corresponding
character in the source character set. The relation between
universal-character-names and source characters, and the choice
if more than one corresponding source character exists, is
implementation-defined.
In Section 5.1.1.2 phase 4, remove the following sentence, which
is no longer needed:
If a character sequence that matches the syntax of a
universal-character-name is produced by token concatenation
(6.8.3.3), the behavior is undefined.
In Section 5.1.1.2 phase 5, remove the phrase ``and
universal-character-name''.
Remove the existing constraints from Section 5.1.1.2; they are
no longer needed. Replace them with the following constraint:
In translation phase 1, a universal-character name must
correspond to a character in the source character set.
In section 6.1.2, uniformly replace universal-character-name with
other-source-character-letter. Add a production
other-source-character-letter:
A source character letter that corresponds to
one of the characters mentioned in Annex I
WG14: Response Code: SD
Please see WG14 N837.
-----------------------------------------------------------------
Comment 3.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 5.1.1.2, 6.8.3.4, 6.8.6, 6.8.9, etc.
Title: standard pragmas should be declarations
Detailed description:
Background
Draft C9X has added six pragmas, which can appear only where
declarations can appear. These pragmas do not act as preprocessing
directives in any way, except that they are themselves not subject
to further preprocessing.
These pragmas are inconvenient to explain and use, since they act
much like declarations -- e.g. they have scope -- but they do not
appear in the language grammar proper, nor can the user easily
write a parameterized macro that expands to such a pragma.
The rules for where these pragmas can appear are complicated and
confusing. In a system where the preprocessor is a separate
program, these pragmas will require special treatment in the
compiler's lexer and parser, since they do not follow the usual
rules for tokenization; e.g. newline is significant.
Suggestion
Instead of
#pragma STDC FP_CONTRACT ON
use the syntax
pragma STDC FP_CONTRACT ON;
Allow standard-pragmas like this to appear at the topmost level,
or at the start of a compound statement, by modifying the grammar for
external-declaration and compound-statement in the obvious way.
You can make `pragma' a keyword if you like, but this isn't
necessary.
Once this change is made, there's no need for the pragma operator;
it can be removed.
WG14: Response Code: PR
-----------------------------------------------------------------
Comment 4.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.8, 6.8.3, 6.8.3.1
Title: The name of __VA_ARGS__ should be specifiable by the user
Detailed description:
Background
Draft C9X introduces a new syntax for macros with varying arguments, e.g.
#define debug(file, format, ...) fprintf(file, format, __VA_ARGS__)
Common existing practice, as with GCC, is to use a syntax where
the varying arguments are named, e.g.
#define debug(file, format, args...) fprintf(file, format, args)
Suggestion
Allow GCC's syntax for macros with varying arguments.
This is an extension to the syntax proposed in draft C9X.
It is more readable, as it lets programmers give useful mnemonic
names to the varying argument lists, thus improving readability
and maintainability.
WG14: Response Code: PR
-----------------------------------------------------------------
Comment 5.
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.7.14
Title: Builtin relational operators should be allowed to be quiet
Detailed description:
Background
Draft C9X requires that A<B raise an exception if either A or B is
a NaN, and provides new functions, e.g. isless(A,B) if quiet
comparisons
(i.e. comparisons that do not raise exceptions) are desired.
Existing practice (e.g. GCC, Sun C) is that A<B is quiet.
The rule of draft C9X is therefore a change to existing practice,
which will break many programs that operate correctly now.
Suggestion
Allow the builtin relational operators to be either noisy or quiet,
at the implementer's option. Provide new functions, e.g.
isless_noisy(A,B), which are guaranteed to be noisy.
WG14: Response Code: BC
IEC 559 arithmetic requires such comparisons to raise
an exception if either operand is a NaN. However, the
comparison does not, by default, cause a trap. Instead
it just sets the exception flag and continues executing.
-----------------------------------------------------------------
Comment 6.
Category: Request for information/clarification
Committee Draft subsection: 6.1.2.4
Title: a compiler should be able to reject jumping past a VLA allocation
Detailed description:
Background
Section 6.1.2.4 paragraph 3 says:
If the object is variably modified and the block is entered by
a jump to a labeled statement, then the behavior is undefined.
It's not clear from this language that a translator is allowed to
reject such programs. If the jump is never executed,
the undefined behavior will never occur. Existing practice (as
in GCC) is to reject such programs at compile-time.
Suggestion
Make it clear that existing practice is allowed by changing the
above wording to:
If the object is variably modified and the block contains a labeled
statement that is a target of a goto statement outside the block,
then the behavior is undefined.
WG14: Response Code: SD
The Committee has made significant changes in this area.
-----------------------------------------------------------------
Comment 7.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.1.2.8.1
Title: two identical objects can compare not equal
Detailed description:
Background
The text says
Two values with the same object representation shall compare
equal, but values that compare equal might have different object
representations.
This is not true for NaNs; two NaNs with the same object representation
must compare not equal.
Suggestion
Replace ``Two values'' with ``Two integer values''.
WG14: Response Code: AL
-----------------------------------------------------------------
Comment 8.
Category: Normative change to existing feature retaining the original
intent
Committee Draft subsection: 6.5.2.1
Title: can't go two past the end of an array
Detailed description:
Background
Paragraph 15 says
If this array would have no elements, then it behaves as if it
has one element, but the behavior is undefined if any attempt
is made to access that element.
This makes it sound like you can address one past this unaccessible
element, which presumably is not intended.
Suggestion
Append ``, or to calculate the address just past that element''
to that sentence.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 9.
Category: Request for information/clarification
Committee Draft subsection: 6.4
Title: casts in sizeof VLA
Detailed description:
Background
The text says
Cast operators in an integer constant expression shall only
convert arithmetic types to integer types, except as part of an
operand to the sizeof operator.
However, with the advent of VLAs, sizeof may need to be evaluated
when applyed to a varying length array type. Are arbitrary casts
allowed inside such sizeof expressions that are within integer
constant expressions? Presumably not, but this needs to be
clarified.
WG14: Response Code: Q
An expression involving a VLA is not an integer expression;
therefore, arbitrary casts are allowed on such expressions
when used in the operand of the sizeof operator.
-----------------------------------------------------------------
Comment 10.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 6.1.3.2
Title: unsuffixed decimal no longer defaults to unsigned
Detailed description:
Background
Draft C9X says that an unsuffixed decimal number is of type int,
long int, or long long int, depending on its value. However, C89
says that its type is int, long int, or unsigned long int.
This can break conforming programs. For example, on a host with
64-bit longs and long longs, the constant 9223372036854775808 is a
valid unsigned long constant in C89, but is prohibited by C9X.
Suggestion
Add a footnote describing this problem, containing the last
sentence of the ``Background'' section above.
WG14: Response Code: EN
-----------------------------------------------------------------
Comment 11.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.1.2.3
Title: inconsistency in comment in 5.1.2.3 example 5
Detailed description:
The last comment in example 5 starts ``not equivalent of'';
it should be ``not equivalent to''.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 12.
Category: Editorial change/non-normative contribution
Committee Draft subsection: 5.2.1, 5.2.1.2
Title: UCNs not allowed in identifiers?
Detailed description:
Section 5.2.1 paragraph 3, last sentence, 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.
This seems to contradict the standard's intent of allowing national
characters in identifiers.
Similar problems are in 5.2.1.2 paragraph 2.
WG14: Response Code: EY
-----------------------------------------------------------------
Comment 13.
Category: Normative change to intent of existing feature
Committee Draft subsection: 7.16.3.4
Title: localtime should be allowed to return NULL
Detailed description:
Background
Draft C9X. as well as C89, requires that localtime return a nonnull
value.
gmtime can return a null pointer, but localtime cannot.
Common existing practice is for localtime to return null if the
argument cannot be represented or is considered to be an illegal
value. For example, if the argument is negative, many Microsoft-based
implementations return null. Another example: if time_t is 64 bits
but int is only 32 bits, and if a very large time_t value is passed
to localtime, the resulting year cannot be stored in the tm_year
member; in such cases, localtime returns null in many
implementations.
Suggestion
Allow localtime to return a null pointer if the broken-down time
cannot be represented, or if the input time_t value is invalid.
Similarly for zonetime, assuming zonetime is retained (see comment
14 below).
WG14: Response Code: AL
Changes along the line of your proposal have been made.
-----------------------------------------------------------------
Comment 14.
Category: Feature that should be removed
Committee Draft subsection: 7.16
Title: changes to <time.h> need a lot of work and should be withdrawn for
now
Detailed description:
Background and comments
Draft C9X introduced a new time struct tmx, new macros
_NO_LEAP_SECONDS and _LOCALTIME, and new functions mkxtime,
zonetime, and strfxtime.
These new functions seem to be an invention of the committee;
they are not based on existing practice, and in some cases
even ignore longstanding existing practice. The new functions
do not address many of the common problems observed with the
C89 primitives, notably with mktime. Nor do they add much
functionality.
For example, a common extension to C, now required by POSIX.1, are
reentrant versions of localtime, gmtime, etc. This fills a
genuine need, but it's not addressed by draft C9X.
There are also other genuine needs that are not addressed; just
look at, say, the harsh words about mktime expressed by the author
of the tide-calculation program XTide in its source code
<http://www.universe.digex.net/~dave/files/xtide-1.6.2.tar.gz>.
Draft C9X addresses few of the needs expressed by this author.
Here are some more detailed comments on technical shortcomings
in this area.
Section 7.16.1 paragraph 3.
The tm_zone member is an integer number of minutes. However,
common practice (e.g. SunOS 4.x, BSD/OS, Linux) is to have a
member named tm_gmtoff that is a long number of seconds. This
is required for proper support of POSIX.1, which lets the user
specify UTC offset to the second; it is also required for
proper support of historical applications. For example, the
UTC offset of Liberia was 44 minutes and 30 seconds until May
1972, and any program running on, say, Linux with the TZ
environment variable set to "Africa/Monrovia" cannot operate
correctly with if the UTC offset is required to be a multiple
of 60 seconds.
The tm_ext and tm_extlen members are an unprecedented kludge
in the standard library spec. This is not C++! If the
specification for struct tmx is incomplete, this suggests that
the editorial work is not done and this type should be
withdrawn from the standard.
Section 7.16.2.3 paragraph 4.
Here, draft C9X added the following new specification for mktime:
If the call is successful, a second call to the mktime
function with the resulting struct tm value shall always
leave it unchanged and return the same value as the first
call. (*)
This specification is reasonable for mkxtime, but for mktime
it requires changes to existing practice in a way that breaks
existing software. Existing software often assumes that
tm_isdst is either negative, 0, or 1; C89 does not guarantee
this, but it is common existing practice, so software that
makes this assumption is portable in practice.
Unfortunately, specification (*) cannot be satisfied without
either adding hidden members to struct tm (which breaks binary
compatibility) or by stuffing more information into tm_isdst
(which breaks the programs described above).
Granted, programs shouldn't assume that a positive tm_isdst
is 1, but it's very common in POSIX.1 programs to see
expressions like `tzname[tm->tm_isdst]', and these expressions
won't work if tm_isdst contains large values.
Section 7.16.2.4 paragraph 3.
If tm_zone was _LOCALTIME, and if tm_isdst is preposterous
(e.g. negative, or INT_MAX), this specification is unclear
about what to do. The comments in 7.16.2.6 don't help much.
Section 7.16.2.6 paragraph 1.
The specification for tm_isdst does not allow for negative
daylight-saving time. I don't know of any historical practice
for this, but POSIX.1 allows it, and implementations that
support POSIX.1 have to allow for it.
Section 7.16.2.6 paragraph 2.
The limits on ranges for struct tmx members are unreasonable.
Common existing practice, for example, is to invoke mktime
with a large value for tm_sec to compute a time stamp at some
distance from the POSIX.1 epoch. If int and long are the same
size, this runs afoul of the new restriction in this section,
which limits tm_sec to one-eighth of the potential range.
With this limitation I cannot even use mktime to compute
today's date on my Unix host from today's time_t value!
The other limits are also unnecessary. A well-written mktime
should work in the presence of arbitrary values in struct
tm members; similarly for mkxtime.
Section 7.16.2.6 paragraph 3.
There are so many errors in this section that it is hard to
determine what is intended. But from what I can tell, the
intent is wrong. For example, it seems to be saying that if
the implementation supports leap seconds, and if local time is
UTC, and if I have a struct tmx that corresponds to 1997-06-30
00:00:00, and then add 1 to tm_mday and invoke mkxtime, I
should get 1997-06-30 23:59:60 due to the intervening leap
second. This is not what I, the programmer, want or expect!
The first sentence in this paragraph reads ``Values S and D
shall be determined as follows''. But the rules that follow
do not _determine_ S and D; they merely place _constraints_
on S and D. This is because the implementation has some leeway
in choosing X1 and X2.
It's not clear in this paragraph whether we're looking at C
code or mathematics. Are we supposed to be using all the C
rules for promotion, conversion, and overflow, or are the
calculations to be done using mathematical integer arithmetic?
The last sentence in the comment about X1 and X2 is
incoherent; I really can't make out what it means.
For the implementation to determine X1 and X2, it needs to
know what D and S are. But D and S are computed from X1 and
X2! More explanation is needed before I can really figure out
what's intended here.
The definition of D is completely unmotivated, and does not
obey the rules of the Gregorian calendar. Among other things,
it uses / and % in places where it should use QUOT and REM.
(And it can't possibly be right without a `100' in it
somewhere. :-) The definition should be rewritten to be
something like the following. (Sorry, I haven't tested this,
as it's less than 30 minutes before the deadline for
submitting comments in the US as this sentence is being
written.)
D = // day offset since 0000-03-01
// contribution from year
Z*365 // number of non-leap days since 0000-03-01
+ QUOT(Z, 4) // Every 4 years ends in a leap year.
- QUOT(Z, 100) // Every 100 years ends in a nonleap year.
+ QUOT(Z, 400) // Every 400 years ends in a leap year.
// contribution from month; note we start from 03-01
+ ((int []){ ...yday offsets, starting in March ...})
[REM(M - 2, 12)]
// contribution from day of month
+ tm_mday - 1
// contribution from time of day
+ QUOT(SS, 86400)
except of course that the expression QUOT(SS, 86400) mishandles
leap seconds as described above.
Section 7.16.3.5
This new function zonetime is if only marginal use; it seems to
be present mostly as a way of defining how mkxtime works.
The definition of leap seconds is incorrect. Leap seconds are
not a UTC-UT1 offset. The absolute value of the difference
between UTC and UT1 is at most 0.9 seconds, by definition.
The changes to 7.16 seem to be hastily edited: there are a number
of what seem to be typographical errors. The changed text is not
explained, and the typos make it hard to understand what was
intended. Here are some of the typos that I spotted despite these
problems:
Section 7.16.1 paragraph 2. _LOCALTIME ``must be outside the
range [-14400, +14400].'' Presumably this should be [-1440,
+1440], i.e. one day's worth not ten.
Section 7.16.2.6 paragraph 3.
The definition for QUOT yields numerically incorrect results
if (b)-(a) or (b)-(a)-1 overflows. I suggest replacing it
with the following definition, which is clearer and free of
problems with overflow. This definition relies on C9X's new
guarantees about integer division.
#define QUOT(a,b) ((a)/(b) - ((a)%(b) < 0))
Similarly, REM can overflow if (b)*QUOT(a,b) overflows. Here
is a better version.
#define REM(a,b) ((a)%(b) + (b) * ((a)%(b) < 0))
The definition of Z can be written more compactly as:
Z = Y - (M < 2);
Section 7.16.3.6 paragraph 5.
``If this value is outside the normal range, the characters stored
are unspecified.'' What is the ``normal range''? The range as
output by localtime, the range of the Gregorian calendar, or
the limits as specified in 7.16.2.6?
Suggestion
Drop all changes to the <time.h> section for this revision of
the C Standard.
Bring in experts in this area for the next revision of the
C Standard. I suggest working together with the members of the
Time Zone Mailing list <[email protected]>.
Build on existing practice rather than relying on committee
inventions, which have been error-prone in this area.
If these suggestions is not followed, a lot of changes are
needed to this section, as suggested by the above discussion;
please contact me if you need more details.
WG14: Response Code: N
------------------------------------------------------------------------
PUBLIC REVIEW COMMENT #11
------------------------------------------------------------------------
Comment 1.
Category: Request for clarification
Committee Draft subsection: 6.5.2.1, 6.1.2.8.2, K.2, K.3.9, K.5.8.
Title: Bitfield widths
Detailed description:
Section 6.5.2.1 #8 states that a bitfield can be declared as type
'int', 'signed int', or 'unsigned int'. It further states that "a
bitfield is interpreted as a signed or unsigned integer type consisting
of the specified number of bits".
However, there is no mention of whether or not the number of bits in a
bitfield is limited to the number of bits in an '[unsigned] int'.
6.5.2.1#8 implies that a bitfield can be declared with the number of
bits in /any/ integer type. This implies that bitfields can be
declared to have any number of bits, up to the number of bits in a
'long' or even a 'long long' integer type.
Presumably, then, the following declaration is conforming and portable:
struct Widdle
{
unsigned int a: 29; // Exceeds bits in UINT_MAX
unsigned int b: 33; // Exceeds bits in ULONG_MAX
};
The width of member 'a' exceeds the minimum ISO width of 'unsigned int'
of 16 bits, so it must take on the type of 'unsigned long int'.
Similarly, the width of member 'b' exceeds the minimum ISO width of
'unsigned long int' of 32 bits, so it must take on the type of
'unsigned long long int'.
This seems like a reasonable interpretation. But is it correct?
Sections K.2, K.3.9, and K.5.8 state that a compiler may allow types
other than 'signed int' and 'unsigned int' for bitfields as an
extension. Assuming that the interpretation above is correct, such
extensions are superfluous; all bitfield types would be equivalent, and
would only be distinguished by their signedness.
Suggestion:
The maximum allowable size for a bitfield should be mentioned in the
standard, perhaps as a footnote to section 6.5.2.1#8:
6.5.2.1
...
[#8]
...
A bitfield is interpreted as a signed or unsigned integer type
consisting of the specified number of bits *.
* This implies that a bitfield may contain any number of bits,
up to the number of bits in the widest integer type (umaxint_t).
If instead it is deemed a limitation that bitfields cannot have a width
that exceeds the number of bits in an '[unsigned] int', then this
should be mentioned, perhaps as a footnote. Further, it should be
noted in appendix K that exceeding this limit is implementation-defined
behavior.
WG14: Response Code: M
The maximum allowable size is a constraint (see paragraph 3).
-----------------------------------------------------------------
RESPONSE CODES
-----------------------------------------------------------------
AD The request is reflected in the current draft.
AL Changes have been made along the lines you suggested.
AM This proposal would introduce an undesired ambiguity.
AN The Committee has voted against this idea.
AW The Standard provides another way to do this.
AY The Committee has voted for this idea.
BC This proposal would invalidate too much existing source code.
BD The Standard reflects the base document in this regard.
BE The Standard remedies a deficiency in the base document.
BS This concerns matters beyond the scope of IEC/ISO WG14 / NCITS J11.
CC This was considered a comment rather than an issue.
CE The Committee believes this is clear enough as is.
CS Compiler ``switches'' can produce multiple implementations.
DA The Committee chose a different approach to deal with this issue.
DI In some cases, this proposal would be difficult to implement.
E This was accepted as an editorial change.
EA Extensions are allowed in this regard, but they are not required.
EF This could not be efficiently implemented on many architectures.
EI The facility was based on an existing implementation.
EL Adding too many facilities would unduly enlarge the language.
EN This proposed editorial change was discussed but not accepted.
EP The Standard reflects widespread existing practice in this regard.
ER This was accepted as an editorial change to the Rationale.
ES This was accepted as an editorial change to the Standard.
EY This editorial change has been made.
FE The Standard must accommodate anticipated future evolution.
IF It was decided to allow implementors freedom in this regard.
II This is an issue for the implementor, not the Standard.
IP This would impair development of portable source code.
LU This was considered to be an invention of limited utility.
M This is a misinterpretation of correct wording in the document.
MC Existing implementations may indeed not meet Standard criteria.
N The Committee discussed this proposal but decided against it.
NB This does not appear to be based on prior art.
NC No change to the existing wording was considered necessary.
NI This was not considered an issue requiring action.
NL The Committee decided not to have ``levels'' of the Standard.
NP A specific proposal is needed before action can be taken.
NT The Standard is not intended to double as a tutorial.
NU XXX The Committee didn't understand this proposal as worded. XXX
OP The Standard supports a one-pass compilation model.
PA This proposal conflicts with too much prior art.
PC This proposal would conflict with other portions of the Standard.
PD The Standard reflects the result of previous discussion of this issue.
PO This proposal would preclude code optimization.
PR The Committee has reaffirmed this decision on more than one occasion.
Q This was considered a request for information, not an issue.
QI Quality of implementation is beyond the scope of the Standard.
RR This issue can be resolved by a careful reading of the Rationale.
RS This issue can be resolved by a careful reading of the Standard.
SC This would run counter to the historical ``spirit of C''.
SD The Committee has made significant changes in this area.
UC Such a constraint on implementations was deemed undesirable.
TE This proposal contains insurmountable technical errors.
TR This is too radical a change to adopt at this stage.
UF This proposal would unduly favor a limited class of architectures.
VA The Standard must accommodate a variety of architectures.
VC The Standard must accommodate a variety of character sets.
VE The Standard must accommodate a variety of environments.
VP The Standard must accommodate a variety of preprocessing methods.
WR The present wording is required for accuracy and completeness.
Y This proposal was accepted.