From: dmm@vnet.ibm.com (dave)
Date: Sun, 6 Sep 92 12:53:27 EDT
Newsgroups: comp.std.c
Subject: Re: How is struct assignment defined (idle query)?
Organization: IBM Canada Lab
News-Software: UReply 3.0
X-X-From: dmm@vnet.ibm.com (Dave Mooney)

            <1992Sep5.165014.7366@sq.sq.com>

In <1992Sep5.165014.7366@sq.sq.com> Mark Brader writes:
>>> Does ANSI say that structure assignment is done by member-wise copy or
>>> by bit-wise copying?
>
> (As I said earlier, I do not believe that the answer to this is clear.)

While the standard does not specify explictly one way or the other, the
fact that the equality operator is not allowed on structs implies that
member-wise copy is certainly allowed.  That is, since

  struct1 = struct2;
  if ( struct1 == struct2 )
    /* blah blah blah */

is not permitted, it would seem to me that the Committee was concerned
that allowing such comparisons would force an implementation to maintain
the integrity of the padding, either by explicitly zeroing it or by only
doing bitwise copying.  I expect that they considered dictating
implementation specifics to be outside their baliwick, so they ducked the
issue by disallowing structure comparisons.  For this reason, I think
that the Standard implicitly allows either bitwise or memberwise copy,
depending on how a particlar implementation can best implement it.

Another consideration is that a structure inside a union is going to be
subject to bitwise copying if assignment is done at the union level, so a
sensible implementation will probably do bitwise copying of a structure
anyway.  But the Standard does not demand this.

>> How would a standard-conforming program tell the difference?
> Since the bitwise copy is a superset of the member-wise copy, a conforming
> program might be able to tell the difference *only if* the standard
> requires bitwise copying and the implementation copies member-wise.
> If that *is* the case, the following program is (I hope) strictly con-
> forming, but prints "Failure!" on an implementation which has certain
> alignment properties and which does member-wise copying.
>    main() {
>         static struct {char a; long b; char c;} zeroes, *p;
>         p = malloc (sizeof *p); if (!p) return 1;
>         memset (p, 'X', sizeof p);
>         *p = zeroes;
>         if (memchr (p, 'X', sizeof p)) printf ("Failure!\n");
>         return 0;
>    }
> Untested code, because I don't have an ANSI C compiler handy.

This isn't strictly-conforming, since it relies on implementation-defined
behaviour (namely, if there is padding between structure members and what
that padding looks like (maybe your compiler explitly sets it all to
'X')).  But the point is moot since the Standard does not demand bitwise
assignment anyway.

Another case is IBM's C/370 compiler, which does *chunkwise* copy for
mixed-alignment assignments between packed and unpacked structures.  That
is, given

  struct s {                 +---+---+---+---+---+---+---+---+
    char a;               x: | a |///|   b   |       c       |
    short b;                 +---+---+---+---+---+---+---+---+
    long c;
  };                         +---+---+---+---+---+---+---+
  struct s x;             y: | a |   b   |       c       |
  _Packed struct s y;        +---+---+---+---+---+---+---+

  x = y;

'a' is copied in one chunk, and 'b' and 'c' are copied in a second chunk.
In this case, the padding vanishes during the copy, and reappears during
a copy going the other way.  (This, of course, proves nothing, but it is
an interesting case to consider).

dave

-------------------------------------------------------------------------
Dave Mooney                                              dmm@vnet.ibm.com
 C Set/2 Development, IBM Canada Lab, 844 Don Mills Rd, Toronto, Ontario
            "If you've got a blacklist, I want to be on it"