From: msb@sq.sq.com (Mark Brader)
Subject: Re: How is struct assignment defined (idle query)?
Organization: SoftQuad Inc., Toronto, Canada
Date: Tue, 8 Sep 92 08:23:16 GMT

> 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.

No; it implies at most the intention that member-wise copy be 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. ...

Not really.  I have looked up the Rationale on this (actually the May 1988
draft of the Rationale, but I think the final one is the same).  In section
3.3.9, it says:

#  The Committee considered, on more than one occasion, permitting
#  comparison of structures for equality.  Such proposals foundered
#  on the problem of holes in structures.  A byte-wise comparison of
#  two structures would require that the holes assuredly be set to
#  zero so that all holes would compare equal, a difficult task for
#  automatic or dynamically allocated variables.  (The possibility
#  of union-type elements in a structure raises insuperable problems
#  with this approach.)  Otherwise the implementation would have to
#  be prepared to break a structure comparison into an arbitrary number
#  of member comparisons; a seemingly simple expression could thus
#  expand into a substantial stretch of code, which is contrary to the
#  _spirit_of_C_.

This is about comparisons and not assignments, and there are some
differences between these operations.  However, the spirit of the
above passage might be applied to structure assignments, and it would
then say "bitwise assignment is in the spirit of C, but the value of
the holes (padding) isn't part of the value of the structure, so you
could do member-wise assignment if you really want".

But note that it doesn't *say* anything about assignments; rather, it
is concerned more with code like this:

	struct {char a; long b;} z, *p;
	p = malloc (sizeof *p);
	p->a = 'x'; p->b = 17;
	z.a = 'x'; z.b = 17;
	if (*p == z) ...

where the problem would be in maintaining equality of the padding even
though the structs did *not* acquire their "equal" values by assignment
of one from the other.


> > 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')).

I made "zeroes" static to get guaranteed initialization, but this fails
for the padding, since the initialization of static things as is if they
were assigned 0, and a value can't be assigned to padding.  The statement

	memset (&zeroes, 0, sizeof zeroes);

should be inserted next to the other memset() call.  Other than this bug,
which Chris Torek also pointed out in email, I believe the code *is*
strictly conforming -- as I said, *if* the standard is interpreted as
requiring bitwise structure assignment.  If run on an implementation
that does memberwise assignment, then whether or not it detects this
(supposed) violation of the standard depends on implementation-defined
behavior, but that does not make the program not strictly conforming.


> But the point is moot since the Standard does not demand bitwise
> assignment anyway.

Anyone feel like asking for an official ruling on that?

> Another case is IBM's C/370 compiler, which does *chunkwise* copy for
> mixed-alignment assignments between packed and unpacked structures. ...
> (This, of course, proves nothing ...

Because the concept of packed and unpacked versions of a structure is
foreign to the standard in the first place.

> ... but it is an interesting case to consider).

Agreed.
-- 
Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb, msb@sq.com
	"I'm a little worried about the bug-eater," she said.  "We're embedded
	in bugs, have you noticed?"		-- Niven, "The Integral Trees"

This article is in the public domain.
Newsgroups: comp.std.c