ISO/ IEC JTC1/SC22/WG14 N767

N767                Some General C9X Issues                   N767
J11/97-131          -----------------------             J11/97-131

                       23 September 1997
                         Tom MacDonald
                         [email protected]

Introduction
------------

Some problems with C9XD11:


------------------------------------------------------------------------

 QUESTION:  Should we use // comments or /*...*/ comments or both?

------------------------------------------------------------------------

Since the C Standard will not forbid an implementation that uses
infinite precision arithmetic, the following example is too strong.


       5.1.2.3  Program execution
       Examples

         5.  Rearrangement   for  floating-point   expressions   is
             restricted because of limitations in precision as well
            ^
            often

             as range.  The implementation cannot  generally  apply
             the  mathematical  associative  rules  for addition or
             multiplication, nor the distributive rule, because  of
             roundoff  error,  even  in the absence of overflow and
             underflow.   Likewise,   the   implementation   cannot
                                      ^^^                 ^
                                      some                s

             generally   replace  decimal  constants  in  order  to
             rearrange expressions.   In  the  following  fragment,
             rearrangements  suggested  by  mathematical  rules for
             real numbers are not valid.  See Annex F.8.
                             ^
                             often


------------------------------------------------------------------------

The following para. doesn't accomplish what was intended.  A complex type
should be just like an array of two elements (structures don't have
elements).  Structures can have padding in the middle and end, arrays
cannot.  Finally, there are no "structured" types.


       6.1.2.5  Types

       [#11] Each complex type  has  the  same  representation  and
       alignment  requirements  as  a  structured  type  containing
                                    ^^^^^^^^^^^^^
                                    an array

       exactly two elements of the  corresponding  real  type;  the
       first  element  is  equal  to  the real part, and the second
       element to the imaginary part, of the complex number.


------------------------------------------------------------------------

The following para. fails to mention restrict-qualified types.

       6.1.2.5  Types

       [#25] Any type so far  mentioned  is  an  unqualified  type.
       Each  unqualified  type  has  three  corresponding qualified
       versions  of  its  type:35  a  const-qualified  version,   a
       volatile-qualified   version,  and  a  version  having  both
       qualifications.  The qualified or unqualified versions of  a
       type  are  distinct  types  that  belong  to  the  same type
       category and have  the  same  representation  and  alignment
       requirements.28   A  derived  type  is  not qualified by the
       qualifiers (if any) of the type from which it is derived.

How about this:

      [#25] Any type so far mentioned is an unqualified type.
      Each unqualified type has seven qualified versions of
      its type,35 corresponding to the combinations of one,
      two, or all three of the const, volatile, and restrict
      qualifiers.  The qualified or unqualified versions of a
      type are distinct types that belong to the same type
      category and have the same representation and alignment
      requirements.28  A derived type is not qualified by the
      qualifiers (if any) of the type from which it is derived.

------------------------------------------------------------------------

Since all "pointers to structures" smell the same, and all "pointers to
unions" smell the same, perhaps we should say something about that here.

       [#26] A pointer to void shall have the  same  representation
       and alignment requirements as a pointer to a character type.
       Similarly, pointers to qualified or unqualified versions  of
       compatible  types  shall  have  the  same representation and
       alignment requirements.28  Pointers to other types need  not
                                ^
                                All pointers to structure types shall
                                have the same representation and alignment
                                requirements as each other.  All pointers
                                to union types shall have the same
                                representation and alignment requirements
                                as each other.

       have the same representation or alignment requirements.

------------------------------------------------------------------------

Use the term "completed" consistently throughout the Draft.  For instance,
the Draft says (in various places):

   |   [#16] The void type comprises an empty set of values; it  is
   |   an incomplete type that cannot be completed.
   |                                     ^^^^^^^^^^
   |
   |   [#22] An array type of unknown size is an  incomplete  type.
   |   It  is  completed,  for  an  identifier  of  that  type,  by
   |           ^^^^^^^^^
   |   specifying the size in a later declaration (with internal or
   |   external  linkage).   A  structure  or union type of unknown
   |   content (as described in 6.5.2.3) is an incomplete type.  It
   |   is   completed,  for  all  declarations  of  that  type,  by
   |        ^^^^^^^^^
   |   declaring the same structure or union tag with its  defining
   |   content later in the same scope.
   |
   |   [#5] 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.68  One  special  guarantee  is  made  in  order  to
   |   simplify  the  use  of  unions:  If a union contains several
   |   structures that share a common initial sequence (see below),
   |   and  if  the  union  object  currently contains one of these
   |   structures, it is permitted to inspect  the  common  initial
   |   part  of  any  of  them  anywhere  that a declaration of the
   |   completed type of the  union  is  visible.   Two  structures
   |   ^^^^^^^^^
   |   share  a  common  initial  sequence if corresponding members
   |   have compatible types (and, for bit-fields, the same widths)
   |   for a sequence of one or more initial members.
   |
   |   [#5] If the type name specifies an array  of  unknown  size,  |
   |   the  size is determined by the initializer list as specified  |
   |   in 6.5.7, and the type of the compound literal  is  that  of  |
   |   the  completed  array  type.   Otherwise (when the type name  |
   |        ^^^^^^^^^
   |
   |   [#2] If a type specifier of the form
   |
   |           struct-or-union identifier                            |
   |
   |   occurs prior to the } following the  struct-declaration-list
   |   that  defines  the  content,  the  structure  or union is an
   |   incomplete type.98  It declares a tag that specifies a  type
   |   that  may  be  used  only  when the size of an object of the
   |   specified type is not  needed.99   If  the  type  is  to  be
   |   completed,  another declaration of the tag in the same scope
   |   ^^^^^^^^^

So, we have "incomplete" types and we have "completed" types.
Change the following paragraph accordingly.


       6.1.2.6  Compatible type and composite type

       [#1] Two types have compatible type if their types  are  the
       same.   Additional  rules  for determining whether two types
       are compatible are described in 6.5.2 for  type  specifiers,  |
       in   6.5.3   for   type   qualifiers,   and   in  6.5.5  for  |
       declarators.36    Moreover,   two   structure,   union,   or
       enumerated  types declared in separate translation units are
       compatible if their tags and members satisfy  the  following
       requirements.   If  one  is  declared  with a tag, the other
       shall be declared with the same tag.  If both  are  complete
                                                           ^^^^^^^^
                                                           completed

       types,  then  the  following  additional requirements apply.

------------------------------------------------------------------------

There's a conflict between the following section:

       6.1.2.8  Representations of types

       [#1] The representations of all types are unspecified except
       as stated in this subclause.

and:

       6.1.2.5  Types

       [#19] The type char, the signed and unsigned integer  types,
       and  the  enumerated  types are collectively called integral
       types.   The  integral   and   real   floating   types   are
       collectively  called  real  types.   The  representations of
       integral types shall define values by use of a  pure  binary
       numeration system.33  The precision of an integral  type  is
       the number of bits it uses to represent values excluding any
       sign and padding bits.  The representations of real floating
       types are unspecified.


Something has to give.  Perhaps:

       [#1] The representations of all types are unspecified except
            ^^^
            Except where previously stated, the

       as stated in this subclause.

------------------------------------------------------------------------

There is a sentence indicating that an object is evaluated.  Only
expressions are evaluated in the Draft.  Here are some excerpts:

   |   Evaluation of an expression may produce side effects.  
   |
   |   [#3] An operator specifies an operation to be performed  (an
   |   evaluation)  that yields a value, or yields a designator, or
   |
   |   [#2] Between the previous and next sequence point an  object
   |   shall  have  its  stored  value modified at most once by the
   |   evaluation of an expression.  Furthermore, the  prior  value
   |
   |   [#5] If an exception occurs  during  the  evaluation  of  an
   |   expression  (that  is,  if  the result is not mathematically
   |
   |   [#8] The order of evaluation of the function designator, the
   |   arguments,   and  subexpressions  within  the  arguments  is

       6.1.2.8.1  General

       [#3] Certain object representations might  not  represent  a
       value  of  that  type.  If such a representation is accessed
       due to evaluation of an object, or if such a  representation
              ^^^^^^^^^^^^^^^^^^^^^^^
              the evaluation of an lvalue that references an object

       is  produced  by  a  side effect that stores into all or any
       part of the object using an lvalue of that  type,  then  the
                                                  ^
                                                  effective
                          [[... maybe you don't need to say "using an
                                lvalue of that type" at all ... who
                                cares how the trap rep. got there? ...]]

       behavior is undefined.39  Such  representations  are  called
       trap representations.

***** add a forward reference for "effective type" (if needed)

------------------------------------------------------------------------

Duplicate footnotes:

What is our policy on footnotes?  Footnote 28 is referenced from
multiple pages.  Footnote 33 and 38 are duplicates (almost).

------------------------------------------------------------------------

Footnote 40 seems to indicate that there are only 2 possibilities.

       40. Thus,  structure  assignment may be implemented element-
                 ^
                 for example,

           at-a-time or via memcpy.

------------------------------------------------------------------------

       6.2.1.3  Real floating and integral

       [#3] An integer may be converted to any  pointer  type.  The  |
       result is implementation-defined, and might not be a pointer  |
       to an object of that type.                                    |

What about "pointer to function" and "pointer to incomplete" types?
Suggested wording change:

    An integer may be converted to any pointer type. The result is
    implementation-defined, and might be improperly aligned or an
    invalid operand for the unary *, [], (), or -> operators.


------------------------------------------------------------------------

There is no "incomplete object type" in C.
There is no "complete type" in C.

       6.2.1.3  Real floating and integral

       [#5] A pointer to a complete or incomplete object  type  may  |
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                         an object or incomplete type

       be  converted  to  a  pointer  to  a  different  complete or  |
                                                        ^^^^^^^^
                                                        object

       incomplete object type.   if  the  resulting  point  is  not  |
       ^^^^^^^^^^^^^^^^^^^^^^                        ^^^^^
       incomplete type                               pointer

       correct  aligned  for  the pointed to  type, the behavior is  |
       ^^^^^^^
       correctly

       undefined.  Otherwise, when converted back again, the result  |
       shall compare equal to the original pointer.53                |


------------------------------------------------------------------------

       53. All  pointers  to character types are correctly aligned.
           In general, the concept correctly aligned is transitive:
           if  a  pointer  to  type  A  is  correctly aligned for a
           pointer to type B, which in turn  is  correctly  aligned
                                                 ^^^^^^^^^^^^^^^^^^
                                                 use roman font

           for  a  pointer  to  type C, then a pointer to type A is
           correctly aligned for a pointer to type C.

------------------------------------------------------------------------

I have a major problem with this footnote.  It seems to me this
footnote forbids bit-addressable machines!  If you read in a
bit address from a file (for example), it might not be correctly aligned
for a character type.  Is this the intent?????

       53. All  pointers  to character types are correctly aligned.
           In general, the concept correctly aligned is transitive:
           if  a  pointer  to  type  A  is  correctly aligned for a
           pointer to type B, which in turn  is  correctly  aligned
           for  a  pointer  to  type C, then a pointer to type A is
           correctly aligned for a pointer to type C.

------------------------------------------------------------------------

What about unnamed bit-fields?

       6.5.2.1  Structure and union specifiers

       [#4]  As  discussed  in  6.1.2.5,  a  structure  is  a  type  |
       consisting  of a sequence of named members, whose storage is
                                    ^^^^^
                                    delete this word?

       allocated in an ordered sequence, and  a  union  is  a  type
       consisting  of  a  sequence  of named members, whose storage
       overlap.

------------------------------------------------------------------------

Need a lead in sentence.

       6.5.5.2  Array declarators
       Examples

         3.
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            The following declarations demonstrate the compatibility
            rules for variably modified types.

                     extern int n;
                     extern int m;
                     void fcompat()
                                  ^
                                  void

                     {
                             int a[n][6][m];
                             int (*p)[4][n+1];                       |
                             int c[n][n][6][m];
                             int (*r)[n][n][n+1];
                             p = a; // Error - not compatible because 4 != 6.
                                                                      ^^^^^^
                                                                      courier

                             r = c; // Compatible, but defined behavior
                                    // only if n==6 and m==n+1.      |
                     }


------------------------------------------------------------------------

Get rid of the parenthetical remark,  and corresponding phrase
in subsequent sentence.


       6.7.1  Function definitions
       Examples

         1.  In the following:

                     extern int max(int a, int b)
                     {
                             return a > b ? a : b;
                     }

             extern is the storage-class specifier and int  is  the
             type  specifier (each of which may be omitted as those
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             are the defaults); max(int a, int b) is  the  function
             ^^^^^^^^^^^^^^^^^
             declarator; and

             [[... snip ...]]

                     extern int max(a, b)
                     int a, b;
                     {
                             return a > b ? a : b;
                     }

             Here int  a,  b;  is  the  declaration  list  for  the
             parameters, which may be omitted because those are the
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             defaults.    The   difference   between   these    two
             ^^^^^^^^


------------------------------------------------------------------------