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 [#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 fill) %h a synonym for %b %n is replaced by a 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 character A number of modified field descriptors %O and %E 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 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. 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 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 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 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 (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 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 to a more logicial position Rationale: 7.17, Alternative spellings , is nowadays positionned after its established position coming from Am.1:1996 to ISO/IEC 9899:1990, i.e. after the subclause. This is now illogical, as (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 ). Proposed solution: Subclause 7.17 should be moved to a new subclause 7.1.x before 7.1.6 . 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 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 " 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 " 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 " 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 "), 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 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 , 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 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 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 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 . 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 , 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 #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 Detailed description: 7.20.3 reserves all names such as int11_t and uint_least22_t. This allows implementations to define them in , 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 is the right place for this.] Add a new macro to : _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 Detailed description: The rules for including 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 // 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 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 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 , 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 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 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 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 and is summarised by me: What is the effect of the following code: #include #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 #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 #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 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 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 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 (nmm1@cam.ac.uk) for comments on the algorithm. I suggest adding the following: Recommended practice An implementation should provide a better random number generator, and not use this example. 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 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 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 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 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 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 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 nmm1@cam.ac.uk. 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 ) 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 and 7.19 Extended multibyte and wide-character utilities ). 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 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 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 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 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 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 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 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 , which therefore will set errno only when an error is detected (see 7.1.4). WG14: Response Code: CE The 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: 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. ). 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 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 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 , 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 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 ) 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 <5p5qfh$4sa$1@blackice.winternet.com> in comp.std.c, strsep() did not get sufficient support at the London meeting), I strongly urge the committee to reconsider its decision and to include strsep() as proposed in the standard. It fixes the problems strtok() has in a clean way, poses no backwards compatibility problems (its name is in a name space that was already reserved in C89), and is a very useful addition to the standard library. Note: I do not propose to *replace* strtok() by strsep(), just to *add* strsep(), thus existing C89 programs can continue to use the older strtok(). 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 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 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 ) 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 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 and )? 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 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 , 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 in para. 4 is imperfectly worded. What it's trying to say, of course, is that the effect of including 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 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 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 "h@.h", 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 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 . 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 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 . 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.