Author: Blaine Garst
Date: 2014-03-14
Subject: N1804: Discussions on DR440, DR441, DR442, DR444, and DR445

Summary

Further conversations with Joseph Myers, author of N1730 and N1731, which gave rise to DR440, DR441, DR442, DR443, and DR444 and DR445 respectively, have brought forth the following additional information and suggestions for these defect reports.

Issues raised in N1730:

DR440

The Oct 2014 discussion on DR440 was misunderstood by the DR editor (me) and is corrected in DR440 version 1.1, and repeated here, to wit:

Proposed Committee Response

To do as suggested, distinguish whether float, double, and long double are IEC or not, requires the addition of new macros, which is a feature, which is not allowed by the mechanism of defect reports.

He suggests that there be some mechanism by which missing definitional issues such as this be remembered such that they be at least considered if not addressed in any subsequent publication of the standard.

As such, I suggest that we adopt and amend the (corrected) committee response, to be:

Suggested Committee Response

DR441

The underlying issue is how, whether, and to what FLT_ROUNDS applies in the presence of a definition of __STDC_IEC_559__, that is, when an implementation makes Annex F normative.

He cites purported confusion by some implementations as to the precedence of Annex F with respect to the Standard. He argues:

If a vendor interprets the standard as permitting one choice and a buyer interprets it as not permitting that choice, that is a defect in the standard; it should be clear what choices are permitted. To quote the ISO/IEC Directives, Part 2, subclause 4.1, "The objective of documents published by ISO and IEC is to define clear and unambiguous provisions in order to facilitate international trade and communication." (I'm referring to edition 6.0, 2011-04).

6.3.8 Normative annexes says "Normative annexes give provisions additional to those in the body of the document.", but doesn't say anything about superseding provisions in the body of the document.

The bottom line is that he feels that it is not stated in the standard that normative annexes should be read as linear extensions to the standard (Forward, p8). The linear treatment is used, for example,

. . .consider: 6.5.5p5 defines semantics for the % operator by which it's unambiguous that INT_MIN % -1 is, according to those semantics, 0. 6.5.5p6 makes INT_MIN % -1 undefined. The undefined behavior takes precedence over the definition in the previous paragraph - that's the normal rule for anything explicitly saying something has undefined behavior (unless Annex L is implemented), that nothing is defined about the program execution from that point onwards, regardless of other provisions that might seem to define something. Why should the present case be different?

If anything, perhaps augmenting Forward.p8 with a statement “Normative Annexes should be interpreted as a linear extension to the standard and take precedence as stated over the standard.” This would allow one to address the specific issue in this DR as “Annex F.2 clearly states that when __STDC_IEC_559__ is defined that float, double, and long double are to be treated as IEC 60559 types.”

DR442

In this case, again, it is more a general precedence rule that is sought.

I don't think adding an "If ... the behaviour is undefined." really addresses the DR - the point is to say that certain things are *not* undefined, not to repeat a statement that things are undefined. That is, to say that where one paragraph (6.5p5) says something is undefined, but something in Annex F says it's defined, the specification saying it's defined is the one that wins. (The same issue of defining which paragraph wins also applies to F.4p1 taking precedence over 6.3.1.4p1.)

Maybe "Where the result of an expression is not mathematically defined or not in the range of representable values for its type, but the behavior is defined in this annex or by reference to IEC 60559, this does not constitute an exceptional condition for the purposes of 6.5p5."? (That doesn't do anything about F.4p1 versus 6.3.1.4p1, but maybe that should be a separate DR.)

Again, as in DR441 above, the confusion around this point might be resolved by normatively specifying the ordering of stated interpretations, such that a normative annex absolutely supersedes the Standard (as suggested above), and perhaps more explicitly, that “it may define previously undefined behaviors, may define what were otherwise implementation defined behaviors, and may redefine as undefined behaviors what were previously well defined behaviors (and any other choices).”

The ISO guidance is somewhat loosely defined and is perhaps too easily and deliberately misinterpreted.

Issues raised in N1731:

DR444

Joseph suggests (absent parenthetical comments such as this):

Suggested Technical Corrigendum

6.7.2.1#1: Move the definition of specifier-qualifier-list to 6.7.7#1. Insert a new definition in 6.7.2.1#1:

specifier-qualifier-alignment-list:

type-specifier specifier-qualifier-alignment-list_opt type-qualifier specifier-qualifier-alignment-list_opt alignment-specifier specifier-qualifier-alignment-list_opt

Change the use of specifier-qualifier-list in the syntax for struct-declaration to specifier-qualifier-alignment-list.

6.7.2#2:

Change "and in the specifier-qualifier list in each struct declaration and type name" to ", in the specifier-qualifier-alignment list in each struct declaration and in the specifier-qualifier list in each type name".

6.7.3#5:

Change "specifier-qualifier-list" to "specifier-qualifier-list, specifier-qualifier-alignment-list or declaration-specifiers" (twice).
(That the wording about duplicate qualifiers and qualifiers used with _Atomic doesn't deal with declaration-specifiers, the syntax production relevant to normal declarations, is a pre-existing problem noticed in the course of preparing this wording.)

(I believe all the semantics and constraints required for alignment specifiers on members are in place, including 6.2.7#1 dealing with cross-translation-unit type compatibility and references to bit-fields and members in 6.7.5.)

DR445

Joseph suggests:

Suggested Technical Corrigendum

Change 6.2.8#2 to:

A fundamental alignment is a valid alignment less than or equal to _Alignof (max_align_t). Fundamental alignments shall be supported by the implementation for objects of all storage durations. The alignment requirements of the following types shall be fundamental alignments:

In 6.2.8#3, change "the contexts in" to "the storage durations of objects for which".

In 6.2.8#4, change "those values returned by an _Alignof expression for fundamental types" to "fundamental alignments".

(Note that the above admits the possibility that e.g. 1 and 4 are fundamental alignments, but 2 isn't, in which case it can't be an extended alignment either. If we want to ensure that 2 isn't a valid alignment at all in that case, rather than possibly having valid alignments that are neither fundamental nor extended, also change "additional implementation-defined set of values" to "additional implementation-defined set of extended alignments" in 6.2.8#4.) In 6.7.5#3, change "in the context in which it appears" to "for an object of the storage duration, if any, being declared". Add a new constraint at the end of 6.7.5#3: "An object shall not be declared with an over-aligned type with an extended alignment requirement not supported by the implementation for an object of that storage duration.".

(This deals with the point that if an over-aligned struct is defined, then objects with that type may be supported with some storage durations but not others, so it is the declaration of an object with that type that can violate a constraint rather than the declaration of the struct.)

In 7.19#2, change "whose alignment is as great as is supported by the implementation in all contexts" to "whose alignment is the greatest fundamental alignment".

(I'm trying to avoid an undesirable implication that if an alignment of e.g. 1MB is supported in all contexts - and it's quite plausible that an implementation can support more or less arbitrary alignments - then max_align_t must have such an alignment and so such an alignment must count as fundamental and so malloc must return memory suitable aligned for it.)