ISO/ IEC JTC1/SC22/WG14 N647

================================================================

                             C9X Revision Proposal
                             =====================
     
     Title: C and C++ structure assignment compatibility
     Author: Tom MacDonald
     Author Affiliation: Cray Research, and SGI company
     Postal Address:     Cray Research Park
                         655F Lone Oak Drive
                         Eagan,  MN  55121
                         USA
     E-mail Address:     [email protected]
     Document Number:    WG14/N647   (X3J11/97-010)
     Telephone Number:   +1-612-683-5818
     Fax Number:         +1-612-683-5307
     Sponsor: X3J11
     Date: 1997-01-07
     Proposal Category:
        __ Editorial change/non-normative contribution
        __ Correction
        XX New feature
        __ Addition to obsolescent feature list
        __ Addition to Future Directions
        __ Other (please specify)  Change of current behavior
     Area of Standard Affected:
        __ Environment
        XX Language
        __ Preprocessor
        __ Library
           __ Macro/typedef/tag name
           __ Function
           __ Header
        __ Other (please specify)  ______________________________
     Prior Art:  C++
     Target Audience:  all C programmers (C++ compatibility)
     Related Documents (if any):  NONE
     Proposal Attached: __ Yes   XX No, but what's your interest?

                                    A proposal will be submitted if
                                    WG14/X3J11 feel this is an issue.

     Abstract: Make C structure copies compatible with C++

     ======================= Cover sheet ends here ==============

     Problem Statement:
     
     Recently I became aware of an incompatibility between C and C++
     that WG14/X3J11 should consider while defining C9X, the next C
     Standard.

     Consider the following example:

        struct S_Pair;

        typedef struct Object {
           struct S_Pair *addr;
           int tag;
        } Object;

         struct S_Pair {
           Object car;
           Object cdr;
         };

         Object x;

         void copy_it(void) {

           x = x.addr->cdr;

         }


      The C++ rules permit the following implementation of the
      structure assignment inside the function copy_it.

         x.addr = x.addr -> cdr.addr;
         x.tag  = x.addr -> cdr.tag;

      The C rules are more strict as indicated in 6.3.16.1, the
      first paragraph under Semantics says:

      In simple assignment(=), the value of the right operand is
      converted to the type of the assignment expression and
      replaces the value stored in the object designated by the
      left operand.

      Note that the value is spoken of as a whole.  There appears to
      be nothing that allows the identity of the right operand to
      change in the middle of the assignment, which is the effect what
      the C++ rules permit.

      The second paragraph under Semantics forbids partial overlap.
      This allows a more efficient implementation of a structure
      assignment (between lvalues) as

         memcpy(&left_operand, &right_operand)

      or an inline equivalent, rather than as

         memmove(&left_operand, &right_operand)

      which would include the extra work needed to accommodate the
      possibility of partial overlap (such as copying through a
      temporary object, or deciding whether to copy bytes from the
      beginning or from the end).  Note that in either case, the
      addresses of the two operands are computed before the copying
      begins.

      The following implementation produces the expected C behavior.

         {
         Object * tmp = &(x.addr->cdr);
         x.addr = tmp->data;
         x.tag  = tmp->tag;
         }

      The question being submitted to this committee is whether C
      should change to become compatible with C++ in this area?

      Things to consider:

         - The C++ rules introduce a QUIET CHANGE into C9X

         - The example in question seems like an unusual case

         - Adopting the C++ rules allows an implementation that
           supports both C and C++ in the same compiler to avoid
           special casing this rarity.

      Finally, if the committee decides to adopt the C++ rules,
      a proposal is needed that shows the wording changes needed.